【问题标题】:How to update state if I have props coming from parent component in React Hooks如果我有来自 React Hooks 中父组件的道具,如何更新状态
【发布时间】:2020-09-24 11:10:10
【问题描述】:

如果我有来自父组件的道具,我会尝试获取更新的文本框值。

这是我的代码 -

const initialState = {
    name: "",
    age: 0
  }

const UserAdd = (props:any) => {
    const {selectedUser} = props;
    
    

    const [state, setState] = useState<any>(initialState);
    const dispatch = useDispatch();

    const onChangeValue = (event:any) => {
        const { name, value } = event.target;
        setState((prevState:any) => (
            { ...prevState, [name]: value }
            ));
    }

    

    const onSubmit = (e:any) => {
        e.preventDefault();
        const { name } = e.target;
        dispatch(addUser(state.name, state.age))
        setState({ ...initialState });
    }

    const onUpdate = (e:any) => {
        e.preventDefault();
        const { name } = e.target;
        console.log(state.name , state.age , "name-age")
    }
    
   

    return (
        <div className="add-user">
            <hr />
            <h2>Add User</h2>
            <hr />
            { selectedUser ? 
            (<form className="form-inline">
                <input type="text" className="form-control mb-2 mr-sm-5 col-md-4" id="email2" placeholder="Enter user name" name="name" value={selectedUser.name} onChange={onChangeValue} />
                <input type="text" className="form-control mb-2 mr-sm-5 col-md-4" id="pwd2" placeholder="Enter user age" name="age" onChange={onChangeValue} value={selectedUser.age} />
                    
                <button type="submit" onClick={onUpdate} className="btn btn-primary col-md-2 mb-2">Update</button>
            </form>)
            :
            (
                <form className="form-inline">
                <input type="text" className="form-control mb-2 mr-sm-5 col-md-4" id="email2" placeholder="Enter user name" name="name" value={state.name} onChange={onChangeValue} />
                <input type="text" className="form-control mb-2 mr-sm-5 col-md-4" id="pwd2" placeholder="Enter user age" name="age" onChange={onChangeValue} value={state.age} />
                    
                <button type="submit" onClick={onSubmit} className="btn btn-primary col-md-2 mb-2">Submit</button>
            </form>
            )
            }
        </div>
    )
}

export default UserAdd;

当没有道具时,即(没有 selectedUser),然后状态更改工作正常,我也能够调度动作。但是当 Props(selectedUser) 可用时,我无法编辑文本框字段并且无法获取更新状态。请有人帮助我。

【问题讨论】:

    标签: javascript reactjs typescript


    【解决方案1】:

    深入了解您的代码.. 当selectedUser 不虚假时,有不同的形式... 当有选定用户时:

    value={selectedUser.name}
    

    应该像其他表单的输入一样:

    value={state.name}
    

    你还需要添加 useEffect 来改变 prop 改变时的状态,你可以这样做:

    useEffect(()=>{
            setState((prevState:any) => (
                  { ...prevState, name: selectedUser.name}
            ));
        },[selectedUser.name])
    

    useEffect 然后将在依赖列表的任何项目与上次渲染不同时执行(在这种情况下,每次更改 selectedUser.name 时)

    【讨论】:

    • 没错,这就是我想问的,如果我们选择了用户十如何更新状态?
    • 我在等
    • 表示在 useEffect 中意外使用了“名称”。
    【解决方案2】:

    如果有selectedUser,则输入字段的value 属性应该是反应式的。目前,它设置为不会对onChangeValue 处理程序做出反应的道具。在value 属性(state.name /state.age)中使用状态并使用selectedUser props 值初始化状态。它可能如下所示 -

    const initialState = {
        name: "",
        age: 0
      }
    
    const UserAdd = (props:any) => {
        const {selectedUser} = props;
        //Button text would be Update or submit that depends on selectedUser.
        const btnText = selectedUser ? "Update" : "Submit";
        //If it founds selected user then set to it otherwise go with initialState
        const [state, setState] = useState<any>(selectedUser || initialState);
        const dispatch = useDispatch();
    
        const onChangeValue = (event:any) => {
            const { name, value } = event.target;
            setState((prevState:any) => (
                { ...prevState, [name]: value }
                ));
        }
    
        const onSubmit = (e:any) => {
            e.preventDefault();
            const { name } = e.target;
            dispatch(addUser(state.name, state.age))
            setState({ ...initialState });
        }
        
        return (
            <div className="add-user">
                <hr />
                <h2>Add User</h2>
                <hr />
                <form className="form-inline">
                    <input type="text" className="form-control mb-2 mr-sm-5 col-md-4" id="email2" placeholder="Enter user name" name="name" value={selectedUser.name} onChange={onChangeValue} />
                    <input type="text" className="form-control mb-2 mr-sm-5 col-md-4" id="pwd2" placeholder="Enter user age" name="age" onChange={onChangeValue} value={selectedUser.age} />
                        
                    <button type="submit" onClick={onUpdate} className="btn btn-primary col-md-2 mb-2">{btnText}</button>
                </form>
            </div>
        )
    }
    
    export default UserAdd;
    

    一旦你像这样设置它,你就不需要有条件地呈现表单。你只需要一张表格。我还添加了一些 cmets。我在这里创建了一个有效的 POC https://codesandbox.io/s/propstostate-react-ssirn

    【讨论】:

    • @AnuragMishra 查看编辑后的答案。另外,我添加了一个与您的问题陈述非常相似的代码框。
    猜你喜欢
    • 2017-12-28
    • 2020-06-19
    • 2021-11-14
    • 1970-01-01
    • 2021-03-14
    • 1970-01-01
    • 2020-11-15
    • 1970-01-01
    • 2019-12-11
    相关资源
    最近更新 更多