如何从子组件 ReactJS 更新父状态

时间:2021-03-26 17:38:13

标签: javascript arrays reactjs

我想要做的是,当我按下删除键时,我想通过传递小于 value 的子值 1 来删除最后一个按钮,然后重新渲染通过地图

    export default function App() {
      const [value, setValue] = useState(2);
      return (
        <div>
          <ChildComponent value={value} setValue={setValue} />
        </div>
      );
    }
    
 export const ChildComponent: React.FC<{
  value: number;
  setValue: (value: number) => void;
}> = ({ value, setValue }) => {
  const [array, setArray] = useState(Array.from(Array(value).keys()));

  const onIncrement = (i: number) => {
    const myArray = array.map((x, index) => {
      if (index === i) {
        return x + 1;
      }
      return x;
    });
    setArray(myArray);
  };

  return (
    <div>
      {array.map((x, i) => {
        return (
          <div>
            <button onClick={() => onIncrement(i)}>{x}</button>
            
          </div>
        );
      })}
      <button onClick={() => setValue(value - 1)}>delete</button>
    </div>
  );
};

1 个答案:

答案 0 :(得分:0)

当您在子组件中点击删除按钮调用 setValue(value - 1) 时,父组件状态的值即 value 会更新,不更新的是子组件的状态 array

由于您仅从子级更新父级的值,因此最好像下面那样自行处理 cchcild 状态更新

export const ChildComponent: React.FC<{
  value: number;
  setValue: (value: number) => void;
}> = ({ value, setValue }) => {
  const [array, setArray] = useState(Array.from(Array(value).keys()));

  const onIncrement = (i: number) => {
    const myArray = array.map((x, index) => {
      if (index === i) {
        return x + 1;
      }
      return x;
    });
    setArray(myArray);
  };

  const handleDelete = () => {
     const updatedArray = array.slice(0 , -1);
     setArray(updatedArray);
     setValue(value - 1);
  }
  return (
    <div>
      {array.map((x, i) => {
        return (
          <div>
            <button onClick={() => onIncrement(i)}>{x}</button>
            
          </div>
        );
      })}
      <button onClick={handleDelete}>delete</button>
    </div>
  );
};

但是如果你希望你的子状态在父 prop 改变时更新,你需要实现一个 useEffect,当 prop 改变时调用它

const isInitialRender = useRef(true);
useEffect(() => {
   if (isInitialRender.current) {
       isInitialRender.current = false;
   } else {
      // you update logic does here
      setArray(prevArray=> prevArray.slice(0, -1));
      // However above logic may not always be to delete, you will have to
      // implement a usePrevious hook to compare how the value prop has
      // and then update the state accordingly
   }
}, [])