简体   繁体   中英

React does not change state after updating state in usestate hook (in custom function form)

I am using usestate hook in react 16.10.2, but after updating initial state using custom function in usetate hook, react does not trigger a re-render(OtherComponent is not rendered), Here is my react component:

import React, { useState, useEffect } from 'react';
import OtherComponent from "./OtherComponent";

function Component(props) {

   const [render, setRender] = useState({0:false, 1:false});
   const display_data = (index) => {
      setRender((prevState) => {
         prevState[index] = !prevState[index];
         return prevState;
      });
   };

   return (
      <>
         {{custom_json_array}.map((record, index) => {
            return (
                  <div>{teacher_render[index] ? 'true' : 'false'}</div>
                  <button onClick={() => display_data(index)}>change state</button>
                  {render[index] ? <OtherComponent /> : ''}
               </div>)
         })}
      </>
   );

}

But strange thing is if I return {...prevState} from hook updater function, everything is normal and re-render is triggerd, I am totally confused? why react behaves like this?!

I assume the problem is that you are mutating render ?

<button 
  onClick={() => setRender({ ...render, [index]: !render[index] })}
>
  change state
</button>

In this example, click on the names to see the custom component and click again to hide

https://codesandbox.io/s/dark-wind-3310q

const CustomComponent = () => (
  <div style={{ marginLeft: 10, background: "red" }}>I'm Selected!</div>
);

function App() {
  const [people] = useState([
    { id: 0, name: "Mario" },
    { id: 1, name: "Luigi" },
    { id: 2, name: "Peach" }
  ]);

  const [selected, setSelected] = useState({});

  return (
    <div>
      {people.map(({ id, name }) => (
        <div
          style={{ display: "flex", cursor: "pointer" }}
          key={id}
          onClick={() => setSelected({ ...selected, [id]: !selected[id] })}
        >
          {name}
          {selected[id] && <CustomComponent />}
        </div>
      ))}
    </div>
  );
}

Your onclick handler is called display_teacher_data in the markup but display_data in the component. Set them to be the same so the state changes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM