简体   繁体   中英

Is there any way to trigger React.useEffect from different component?

Imagine two components like this in React:

import MyComponent2 from "./components/MyComponent2";
import React from "react";

export default function App() {
  const [myState, setMyState] = React.useState([]);

  React.useEffect(() => {
    console.log("useEffect triggered");
  }, [myState]);

  return <MyComponent2 myState={myState} setMyState={setMyState} />;
}
import React from "react";

export default function MyComponent2(props) {
  const [inputValue, setInputValue] = React.useState("");

  function handleChange(e) {
    setInputValue(e.target.value);
    let list = props.myState;
    list.push(`${e.target.value}`);
    props.setMyState(list);

    console.log(props.myState);
  }

  return (
    <div>
      <input
        type="text"
        value={inputValue}
        name="text"
        onChange={handleChange}
      />
    </div>
  );
}

As you can see I am making changes with props.setMyState line in second component. State is changing but Somehow I could not trigger React.useEffect in first component even tough It is connected with [myState]. Why?

In short form of my question: I can not get "useEffect triggered" on my console when i make changes in input

Instead of providing myState and setMyState to MyComponent2 , you should only provide setMyState and use the functional update argument in order to access the current state.

In your handleChange function you are currently mutating the React state ( modifying it directly ):

let list = props.myState; // This is an array that is state managed by React
list.push(`${e.target.value}`); // Here, you mutate it by appending a new element
props.setMyState(list);
// ^ You update the state with the same array here,
// and since they have the same object identity (they are the same array),
// no update occurs in the parent component

Instead, you should set the state to a new array (whose object identity differs from the current array):

props.setMyState(list => {
  const newList = [...list];
  newList.push(e.target.value);
  return newList;
});

// A concise way to write the above is like this:
// props.setMyState(list => [...list, e.target.value]);

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