How to update props of React Component rendered using ReactDOM.render()
There is no magic at work here, you just need to re-render it.
Just wrapper your rendering into a function, eg:
function renderReactNavbar( tabs = [] ) {
ReactDOM.render(
<NavBar
currencyTabs = { tabs }
/>, document.getElementById("navbar-root")
);
}
and call it after you load / update your data.
Alternatively, you choose to load your data from inside react, which might be a better choice in the long run.
If you have internal state, this might be somewhat harder to handle. You could consider moving to a props only component (but since you don't share any relevant code of your react component, it is hard to say)
A small example of how it could look would be
// the render method, takes a component and props, and renders it to the page
function renderComponent( component, props ) {
const target = document.querySelector('#container');
ReactDOM.render( React.createElement( component, props ), target );
}
// gets the tabs from the input field, splits based on ,
function getTabsFromInput() {
return document.querySelector('#tabs').value.split(',');
}
// small presentational component, shows the tabs and redirects selection changes through a callback
const Tabs = ({ tabs, selectedTab, onSelectionChanged }) => {
return tabs && <div>{ tabs.map( (tab, key) => {
return <h1 key={key} className={classNames( { 'active': key === selectedTab } ) } onClick={ () => onSelectionChanged( key ) }>{ tab }</h1>;
} ) }</div>;
};
// some initiations
window.addEventListener('load', function() {
// keep a local variable with the data
let defaultProps = {
onSelectionChanged: updateSelection,
selectedTab: 0,
tabs: getTabsFromInput()
};
// handles selection changes
function updateSelection( newTab ) {
defaultProps = {...defaultProps, selectedTab: newTab };
renderComponent( Tabs, defaultProps );
}
// adds an event listener for click events to initiate tab changes
document.querySelector('#updateTabs').addEventListener('click', function() {
defaultProps = {...defaultProps, tabs: getTabsFromInput() };
// render on update
renderComponent( Tabs, defaultProps );
});
// initial render
renderComponent( Tabs, defaultProps );
});
.active {
background-color: blue;
}
<script id="react" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.2/react.js"></script>
<script id="react-dom" src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.6.2/react-dom.js"></script>
<script id="classnames" src="https://cdnjs.cloudflare.com/ajax/libs/classnames/2.2.5/index.js"></script><div id="container"></div>
<input type="text" value="tab1,tab2" id="tabs" />
<button id="updateTabs" type="button">Update tabs</button>
rex
Updated on June 17, 2022Comments
-
rex almost 2 years
I am trying to integrate react into my angularjs webapp.
In my controller I create the component, which initially has array props that are empty. When the app is done initializing, I want to update the props again. Do I do this by calling
ReactDOM.render()
again or can I keep a reference to this instance and just do something likeupdateProps(newProps)
?This is called from my controller:
ReactDOM.render( <NavBar currencyTabs = {[]} />, document.getElementById("navbar-root") );
And then when the data is done loading i need to update the
currencyTabs
with a full array ...I understand how react components props update from parent to child, but I don't quite get how I can do this from plain JS.
-
rex over 6 yearsThank you -this is what I was wondering. Unfortunately loading the data inside the component is not an option at this time due to the nature and complexity of our app.
-
Icepickle about 6 yearsIt doesn't have state, it has props, at least from what we can see. If it has an internal state to manage the currencyTabs, that's another question. The lifecycle methods won't intervene here either, as this is directly rendered to a div element, react is simply used to render 1 single component)
-
Icepickle about 6 years@rex Yeah, well then you have to make sure you reload at the correct times. So if you have a change in your data, just call the re-render. I am however unsure how internal state works in this case
-
John Hatton over 4 yearsThis answer is great, but I misunderstood it. So, note that might help someone else:
ReactDom.render()
does not give you a clean-slate; it just updates the component. So if your props did not change, it will not re-render. If you are fighting a system that isn't totally functional, and you have to doReactDom.unmountComponetnAtNode()
first (or introduce some other prop just for the sake of forcing an update). Have it working? OK good, now look for some way to remove that hack :-) -
spritecodej over 4 yearsI want to change just component and check the "componentWillRecieveProps". Then I apply some code in "componentWillRecieveProps" that is good working
-
ruffin about 2 years@JohnHatton's comment is important, afaict, but unfortunately contains a typo in
unmountComponentAtNode
! Here'sunmountComponentAtNode
in React's docs, and here's an answer from Dan Abramov saying why it's essential to use for [a subset of?] cases we're discussing, if I'm reading him right.