React.js:如何使用钩子从父项重置组件的值

时间:2019-10-17 17:18:45

标签: reactjs react-hooks

我有一个组件,该组件使用另一个从文本框输入和输出值的组件。我可以从子组件中获取输入的值,我的问题是重置子组件的值。现在,一旦执行了onadditem函数,在单击onadditem的addbutton之前,自动完成输入框仍将保留该值。

这是父组件:

const [state, setState] = useState({
  id: props.spendItem.id,
  isNew: (props.spendItem.id == -1), 
  description: '', 
  vendor: ''
});

const onAddItem = (e) => {
  setState({...state, id: -1, description: '', isNew: true, vendor:''});
}

const setAutoCompleteValue = (e) => {
  setState({...state, vendor: e})
}

var newItem = (<div>
  <AutoComplete 
    items={vendors} 
    name='vendor' 
    value={state.vendor} 
    setValue={setAutoCompleteValue}
  />
  <button onClick={onAddItem}>+</button>
</div>);

这是输入组件

const AutoComplete = props => {
  const [typedValue, setTypedValue] = useState(props.value.name || '');

  useEffect(() => {
    props.setValue(getValue());
  }, [typedValue]);

  const onChange = (e) => {
  // i process my change for the value here
  }

  const getValue = () => {
    return typedValue;
  }

  return (
    <div>
      <input 
        id='auto_input' 
        name='name' 
        onChange={onChange} 
        value={typedValue}
      />
    </div>
  );
}

export default AutoComplete;

1 个答案:

答案 0 :(得分:1)

这是因为您要将父组件的值传递给子组件,但是只在一次子组件状态下初始化它,而在下一次父组件更改时不更新子组件。因此,在父级中设置值将不会继续反映在子级中。

因此,您需要确定是将状态存储在父组件中还是存储在Autocomplete本身中。我不确定在状态更改时到底要发生什么副作用,但是这是一个基本示例,说明如何在添加项目时使“自动完成”成为一个哑组件并从父级重置值。我从父级移除了大多数无关状态:

const App = () => {
  const [vendor, setVendor] = React.useState("");
  const [items, setItems] = React.useState([]);

  const onAddItem = () => {
    setItems([...items, vendor]);
  }

  React.useEffect(() => {
    setVendor("");
  }, [items])

  return <div>
            <AutoComplete value={vendor} setValue={setVendor}/>
    <button onClick={onAddItem}>+</button>
    <div style={{ padding: 25}}>
      {items.map(item => <div>{item}</div>)}
    </div>
            </div>
}

const AutoComplete = ({ value, setValue}) => {

const onChange = (e) => {
  setValue(e.target.value)
}

const getValue = () => {
  return typedValue;
}
  return (
    <>
        <input id='auto_input' name='name' onChange={onChange} value={value}/>
    </>
)
}

ReactDOM.render(<App/>, document.getElementById("root"))

Codepen here