Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update props of React Component rendered using ReactDOM.render()

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 like updateProps(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.

like image 297
rex Avatar asked Feb 07 '18 10:02

rex


People also ask

What does ReactDOM render () do?

The ReactDOM.render() function takes two arguments, HTML code and an HTML element. The purpose of the function is to display the specified HTML code inside the specified HTML element.

Which component is passed to ReactDOM render () method?

render() The first argument is the element or component we want to render, and the second argument is the HTML element (the target node) to which we want to append it. Generally, when we create our project with create-react-app , it gives us a div with the id of a root inside index.

Can props be updated in React?

A component cannot update its own props unless they are arrays or objects (having a component update its own props even if possible is an anti-pattern), but can update its state and the props of its children.

What is difference between ReactDOM and render render?

render renders your components to the DOM while a component's render returns the elements that make up the component.


1 Answers

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>
like image 111
Icepickle Avatar answered Oct 18 '22 09:10

Icepickle