如何使用React-Enzyme模拟改变孩子的价值

时间:2019-07-31 07:43:37

标签: reactjs jestjs enzyme

给出以下简单组件:

function ValueInput (props) {
  const [val, setVal] = useState(props.value);

  return <input value={val} onChange={v => setVal(v)}/>;
}

function MyComponent (props) {
  const [val, setVal] = useState(props.value);

  return (
    <div>
      <div>{val}</div>
      <ValueInput value={val}/>
    </div>
  );
}

我安装它们是为了用酶和Jest测试它们:

const component = mount(<MyComponent value={42}/>);
const inputEl = component.find('input');

如何模拟更改内部输入的值并将其反映在div中?我正在尝试使用以下代码,但是它不起作用:

console.log(component.debug());
inputEl.simulate('change', { target: { value: 24 } });
// component.update();
console.log(component.debug());

即使强制更新也不会更改值。打印的组件保持不变:

  <MyComponent value={42}>
    <div>
      <div>
        42
      </div>
      <ValueInput value={42}>
        <input value={42} onChange={[Function: onChange]} />
      </ValueInput>
    </div>
  </MyComponent>

1 个答案:

答案 0 :(得分:1)

在您的代码中

function ValueInput (props) {
  const [val, setVal] = useState(props.value);

  return <input value={val} onChange={v => setVal(v)}/>;
}

您仅更改子组件的值,不影响父组件的值,因为您没有调用父组件的setVal方法。

您需要更新代码:

function ValueInput (props) {
  const [val, setVal] = useState(props.value);

  const handleChange = e => {
    const {value} = e.target;
    setVal(value);
    props.setParentVal(value) // Pass the changed value to the parent
  }

  return <input value={val} onChange={handleChange}/>;
}

function MyComponent (props) {
  const [val, setVal] = useState(props.value);

  return (
    <div>
      <div>{val}</div>
      <ValueInput value={val} setParentVal={setVal}/>
    </div>
  );
}

还要查看代码,没有必要在子组件内部复制状态,您可以直接使用父代的方法来操纵和存储输入值:

function ValueInput ({val, setVal}) {
   return <input value={val} onChange={setVal}/>;
}

function MyComponent (props) {
  const [val, setVal] = useState(props.value);

 const handleChange = e => {
    const {value} = e.target;
    setVal(value);
  }

  return (
    <div>
      <div>{val}</div>
      <ValueInput value={val} setVal={handleChange}/>
    </div>
  );
}