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

How to set an object passed via props into hooks local state

已将 props 设置为状态,但无法访问内部属性

通过模型如下

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

我正在调用模型如下

<VisitorModal visitor={v}/>

模型在这里

import React, { useState, useEffect } from "react";
import { Modal, Form, Button } from "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 })}
    >
      {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({ modalOpen: false })}>Cancel</Form.Button>
            </Form.Group>
          </Form>
        </Modal.Description>
      </Modal.Content>
    </Modal>
  );
};

export default VisitorModal;

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

原因是因为您没有在初始状态对象或事件处理程序中为 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()

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

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>
  );
};