简体   繁体   English

React:在子组件中更改了 state。 如何查看父组件的变化?

[英]React: Changed state in Child component. How to see the change in parent component?

For a website I am working on I have made a component with checkboxes that triggers a state change in a parent component.对于我正在使用的网站,我制作了一个带有复选框的组件,该复选框会触发父组件中的 state 更改。 I have checked in the console through the child component that the state is changed, but I want the parent component to "notice" the change too.我已通过子组件在控制台中检查 state 已更改,但我希望父组件也“注意到”更改。 I have tried useEffect and componentDidUpdate but they both do not get triggered by the state change.我已经尝试过 useEffect 和 componentDidUpdate 但它们都不会被 state 更改触发。

To clarify, the structure looks like this:澄清一下,结构如下所示:

Parent: Has the initial state Child: Gets access to state through parent, and changes state Parent:拥有初始的 state Child:通过 parent 获取到 state,并更改为 state

On a page refresh the parent notices the state change, but I want this without having to refresh the page.在页面刷新时,父级注意到 state 更改,但我希望无需刷新页面即可完成此更改。

I hope this makes sense, thank you in advance:)我希望这是有道理的,提前谢谢你:)

Is this what you are looking for?这是你想要的?

import React, { useState } from "react";

const Parent = () => {
  const [someState, setSomeState] = useState("Initial Some State");

  const onChangeSomeState = (newSomeState) => {
    setSomeState(newSomeState);
  };

  return (
    <div>
      Parent:
      <Child
        someState={someState}
        onChangeSomeState={onChangeSomeState}
      ></Child>
    </div>
  );
};

const Child = ({ someState, onChangeSomeState }) => {
  const handleChangeStateClick = () => {
    onChangeSomeState("New Some State from Child");
  };
  return (
    <div>
      Child:{someState}
      <input
        type="button"
        onClick={handleChangeStateClick}
        value="Change state from Child"
      ></input>
    </div>
  );
};

export default Parent;

If I understood your issue correctly, you can pass a callback function into child component.如果我对你的问题的理解正确,你可以将回调 function 传递给子组件。 In that way, you'll receive value from callback in your parent component like this:这样,您将从父组件中的回调接收值,如下所示:

const ParentComponent = () => {
    const [someState, setSomeState] = useState()

    const childCallback = (value) => {
       setSomeState(value)
    }

    return <ChildComponent callback={childCallback} />
}

The nature of react means that data flows down the dom tree. React 的本质意味着数据沿着 dom 树向下流动。 This is made possible using props.使用道具可以做到这一点。

When props change it is noticed by react and that causes the recipient of the props to re-render.当道具发生变化时,反应会注意到它,这会导致道具的接收者重新渲染。 However, as you have discovered this is a uni-directional relationship, only ever going parent to child.但是,正如您所发现的那样,这是一种单向关系,永远只能是父子关系。

The beauty of javascript is that you can treat functions just like strings or numbers and pass them around. javascript 的美妙之处在于您可以像对待字符串或数字一样对待函数并传递它们。 In this case as props.在这种情况下作为道具。

So while the child can't 'tell' the parent something has changed directly, the parent can pass in a function that the child can use to make the change known.因此,虽然孩子不能直接“告诉”父母发生了一些变化,但父母可以传入一个 function,孩子可以使用它来告知变化。

This pattern of passing down a value from a parent and a 'handler' function the child can use to notify the parent is extremely common and a good one you get your head around.这种从父母和孩子可以用来通知父母的“处理程序” function 传递值的模式非常普遍,并且是一个很好的模式。

Take a standard text input as an example.以标准文本输入为例。

const Parent = () => {
  // This is our parent's state
  const [inputValue, setInputValue] = useState('hello world');

  // This is the handler we will give to the child to let us know of changes
  const handleInputChange = (e) => setInputValue(e.target.value) 

  return <input
    value={inputValue}
    onChange={handleInputChange} 
  />
}

In the above example the child (the input) when it changes will call the function supplied to it and that will update the parent's state. Any state updates on a react component (just like a prop change) will cause a re-render and therefore a visual update.在上面的示例中,子项(输入)在更改时将调用提供给它的 function,这将更新父项的 state。反应组件上的任何 state 更新(就像道具更改一样)将导致重新渲染,因此视觉更新。

I used a built in <input> in any child you write yourself just needs to accept a 'handler function' which you call inside your child when you want to let the parent know that something has happened.我在你自己编写的任何孩子中使用了一个内置的<input> ,当你想让父母知道发生了什么事时,你只需要接受一个你在孩子内部调用的“处理函数”。

As my understanding, if I don't get wrong, I think you should pass the trigger event from parent to child as props.据我了解,如果我没弄错的话,我认为你应该将触发事件作为道具从父母传递给孩子。

parent ( functional component + hook ):父级(功能组件+钩子):

const [ userName, setUserName ] = useState("");

return(
  <Child doChangeProps={setUserName} />
)

child ( functional component + hook ):孩子(功能组件+钩子):

const { doChangeProps } = props;

return(
  <input onChange={ e => { doChangeProps(e); } } />
)

or, you can use context for more simple data flow.或者,您可以使用上下文来实现更简单的数据流。

function ParentComponent(){
    const [state, setState] = useState()

    useEffect(() => {
       console.log({ state });
    },[state])

    return <ChildComponent state={state} setState={setState} />
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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