简体   繁体   English

从父组件更改反应挂钩状态

[英]Change react hook state from parent component

I have a hook component like this:我有一个这样的钩子组件:

import React, { useState} from "react";

const MyComponent = props => {
  const [value, setValue] = useState(0);
  const cleanValue = () => {
    setValue(0);
  };

  return (<span><button onClick={()=>setValue(1)}/>{value}<span>)
}

I want to reset value from the parent component.我想重置父组件的值。 How I can call clean value from parent component?如何从父组件调用干净的值? the parent component is a stateful component.父组件是有状态组件。

If the parent has to control the child state then probably the state must reside in the parent component itself.如果父级必须控制子状态,那么该状态可能必须驻留在父组件本身中。 However you can still update child state from parent using ref and exposing a reset method in child.但是,您仍然可以使用 ref 从父级更新子状态并在子级中公开重置方法。 You can make use of useImperativeHandle hook to allow the child to only expose specific properties to the parent您可以使用useImperativeHandle钩子来允许子只向父公开特定属性

 const { useState, forwardRef, useRef, useImperativeHandle} = React; const Parent = () => { const ref = useRef(null); return ( <div> <MyComponent ref={ref} /> <button onClick={() => {ref.current.cleanValue()}} type="button">Reset</button> </div> ) } const MyComponent = forwardRef((props, ref) => { const [value, setValue] = useState(0); const cleanValue = () => { setValue(0); }; useImperativeHandle(ref, () => { return { cleanValue: cleanValue } }); return (<span><button type="button" onClick={()=>setValue(1)}>Increment</button>{value}</span>) }); ReactDOM.render(<Parent />, document.getElementById('app'));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script> <div id="app"/>

From the React documentation about Fully uncontrolled component with a key :从 React 文档中关于Fully uncontrolled component with a key

In order to reset the value..., we can use the special React attribute called key .为了重置值...,我们可以使用名为key的特殊 React 属性。 When a key changes, React will create a new component instance rather than update the current one .当一个key改变时, React 将创建一个新的组件实例而不是更新当前的实例 Keys are usually used for dynamic lists but are also useful here.键通常用于动态列表,但在这里也很有用。

In this case, we can use a simple counter to indicate the need for a new instance of MyComponent after pressing the Reset button:在这种情况下,我们可以使用一个简单的计数器来指示在按下Reset按钮后需要一个新的MyComponent实例:

 const { useState } = React; const Parent = () => { const [instanceKey, setInstanceKey] = useState(0) const handleReset = () => setInstanceKey(i => i + 1) return ( <div> <MyComponent key={instanceKey} /> <button onClick={handleReset} type="button">Reset</button> </div> ) } const MyComponent = () => { const [value, setValue] = useState(0) return ( <span> <button type="button" onClick={()=>setValue(v => v + 1)}>{value}</button> </span> ) }; ReactDOM.render(<Parent />, document.getElementById('app'));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script> <div id="app"/>

You can't / shouldn't.你不能/不应该。 Using hooks instead of stateful class components doesn't change the fact that if you want the parent to own the state, you need to declare the state in the parent.使用钩子而不是有状态的类组件不会改变这样一个事实,即如果您希望父级拥有状态,则需要在父级中声明状态。

It should look something like this, depending on when you want to reset the value (here I used another button):它应该看起来像这样,具体取决于您何时要重置该值(这里我使用了另一个按钮):

const MyButton = (props) = (
  // Whatever your button does, e.g. styling
  <span>
    <button {...props} />
  <span>
)


const Parent = props => {
  const [value, setValue] = useState(0);
  const cleanValue = () => setValue(0);
  return (
    <div>
      <MyButton onClick={() => setValue(1)}>
        {value}
      </MyButton>
      <button onClick={cleanValue}>
        Reset
      </button>
    </div>
  )
}

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

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