Component in Reactjs re-rendering child components without need, how to get around this?

Asked

Viewed 347 times

0

When a component Father consequently updates its Son(s) (s) also and(are) updated(s), without at least changing any value of its props and states, for example:

function Filho({item}) {
  React.useEffect(() => {
    console.log('atualiza');
  });
  return (
    <div>{item.id} - {item.name}</div>
  );
}
function Pai() {
  const [items, setItems] = React.useState([
    { id:'1', name:'example 1'},
    { id:'2', name:'example 2'}
  ]);
  const [value, setValue] = React.useState('');
  return (
    <div>
      <div>
        <input type="text" 
          onChange={e => setValue(e.target.value)}
          value={value}
        />
      </div>
      <div>
        {
          items.map((item, i) =>
            <Filho key={i} item={item}/>
          )
        }
      </div>
    </div>
 );
}

ReactDOM.render(<Pai/>, document.getElementById('root'));
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.9.0/umd/react-dom.production.min.js"></script>
<div id="root">Aguarde ...</div>

every time the component is typed <Filho /> also renders all items again, proposing an unnecessary rework has how to solve this re-rendering?

1 answer

1


There is, with the React.memo (or in classes with Purecomponent that compares the state and props superficially, taking proper care of complex objects, that is, this feature are for components with simple objects) as follows:

let Filho = React.memo(({item}) => {
  React.useEffect(() => {
    console.log('atualiza');
  });
  return (
    <div>{item.id} - {item.name}</div>
  );
});
function Pai() {
  const [items, setItems] = React.useState([
    { id:'1', name:'example 1'},
    { id:'2', name:'example 2'}
  ]);
  const [value, setValue] = React.useState('');
  return (
    <div>
      <div>
        <input type="text" 
          onChange={e => setValue(e.target.value)}
          value={value}
        />
      </div>
      <div>
        {
          items.map((item, i) =>
            <Filho key={i} item={item}/>
          )
        }
      </div>
    </div>
 );
}

ReactDOM.render(<Pai/>, document.getElementById('root'));
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.9.0/umd/react-dom.production.min.js"></script>
<div id="root">Aguarde ...</div>

in this case, by typing <input/> the component is not re-rendered (as there were no changes) and this has a performance gain, but as was said has its constraints.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.