如何将通过道具传递的对象设置为挂钩局部状态

时间:2019-04-28 06:26:59

标签: reactjs react-hooks

已通过道具设置为状态,但无法访问内部属性

通过模型如下

let v = {
    "id": "6ccd12a3-802b-4ff6-ab6d-0f66f9df1e99",
    "mac": "a4:5e:60:f2:89:bf"
}

我按如下所述调用模型

<VisitorModal visitor={v}/>

模型在这里

从'react'导入React,{useState,useEffect}; 从'semantic-ui-react'导入{模态,形式,按钮};

const VisitorModal = ({ visitor }) => {

    const [ state, setState ] = useState({
        modalOpen: false,
        v: visitor,
    });

    const handleOnChange = (e) => {
        console.log(e.target.name);
        console.log(e.target.value);
        state[e.target.name] = e.target.value;
    }

    useEffect(() => {
        setState(prevState => ({
            ...prevState,
            v: visitor
        }));
      }, [visitor]);

    return (
        <Modal trigger={<Button onClick={ () => setState({ modalOpen: true }) }> View/Edit Visitor </Button>} centered={false}
                open={state.modalOpen}
                onClose={ () => setState({modalOpen: false}) }
                // closeOnEscape={closeOnEscape}
                // closeOnDimmerClick={closeOnDimmerClick}
            >
            {JSON.stringify(state)}
            {/* {JSON.stringify(state)} */}
                <Modal.Header> View/Edit Visitor </Modal.Header>
                <Modal.Content image>
                    {/* <Image wrapped size='medium' src='/images/avatar/large/rachel.png' /> */}
                    <Modal.Description>
                        {/* <Header>Default Profile Image</Header> */}
                        <Form>
                            <Form.Group widths="equal">
                                <Form.Input label="MAC" placeholder="mac" value={state.v.mac} onChange={handleOnChange} />
                                <Form.Input label="Name" placeholder="Name" value={state.v.name} onChange={handleOnChange} />
                            </Form.Group>
                            <Form.Group>
                                <Form.Button >Save</Form.Button>
                                {/* <Form.Button disabled={!state.orgName}>Save</Form.Button> */}
                                <Form.Button onClick={() => setState({ modalOpen: false })}>Cancel</Form.Button>
                            </Form.Group>
                        </Form>
                    </Modal.Description>
                    {/* <button >click</button> */}

                </Modal.Content>
            </Modal>
    )
}

export default VisitorModal;

error is TypeError: Cannot read property 'mac' of undefined

2 个答案:

答案 0 :(得分:1)

原因是因为您没有在初始状态对象或事件处理程序中为v设置值。 useState()不会合并对象值,而是会覆盖它们。因此,您有两个选择:使用useReducer,或为modalOpenv使用单独的状态对象。

假设您适当地更新了render()方法,这应该使用后一种方法来解决:

const VisitorModal = ({ visitor }) => {
  const [ modalOpen, setModalOpen ] = useState(false);
  const [ v, setV ] = useState(visitor);

  // Update `v` when the visitor prop changes.
  useEffect(() => {
    setV(visitor);
  }, [visitor]);
  const handleChange = e => setV({ ...v, [e.target.name]: e.target.value });
  return (
       <Form.Input label="MAC" placeholder="mac" value={v.mac} onChange={handleChange} />
  );
}

您的事件处理程序现在可以独立引用setV()setModalOpen()

答案 1 :(得分:0)

您在切换模型时错过了检索以前的值,因此对象缺少访问者属性。试试这个

return (
    <Modal
      trigger={<Button onClick={() => setState((prev) => ({ ...prev, modalOpen: true }))}> View/Edit Visitor </Button>}
      centered={false}
      open={state.modalOpen}
      onClose={() => setState(setState((prev) => ({ ...prev, modalOpen: false }))}
    >
      {JSON.stringify(state)}
      <Modal.Header> View/Edit Visitor </Modal.Header>
      <Modal.Content image>
        <Modal.Description>
          <Form>
            <Form.Group widths="equal">
              <Form.Input label="MAC" placeholder="mac" value={state.v.mac} onChange={handleOnChange} />
              <Form.Input label="Name" placeholder="Name" value={state.v.name} onChange={handleOnChange} />
            </Form.Group>
            <Form.Group>
              <Form.Button>Save</Form.Button>
              <Form.Button onClick={() => setState(setState((prev) => ({ ...prev, modalOpen: false }))}>Cancel</Form.Button>
            </Form.Group>
          </Form>
        </Modal.Description>
      </Modal.Content>
    </Modal>
  );
};