Ad
How To Simulate Changing The Value Of A Child With React-Enzyme
Given the following simple components:
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>
);
}
I'm mounting them in order to test them with Enzyme and Jest:
const component = mount(<MyComponent value={42}/>);
const inputEl = component.find('input');
How do I simulate changing the value of the inner input and have it reflected in the div? I'm trying with the following code, but it doesn't work:
console.log(component.debug());
inputEl.simulate('change', { target: { value: 24 } });
// component.update();
console.log(component.debug());
Even forcing the update doesn't change the values. The printed component stays the same:
<MyComponent value={42}>
<div>
<div>
42
</div>
<ValueInput value={42}>
<input value={42} onChange={[Function: onChange]} />
</ValueInput>
</div>
</MyComponent>
Ad
Answer
In your code
function ValueInput (props) {
const [val, setVal] = useState(props.value);
return <input value={val} onChange={v => setVal(v)}/>;
}
You're only changing the value of the child component, the value of the parent is not affected, since you didn't call the parent's setVal
method.
You need to update your code:
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>
);
}
Also looking at the code, it is not necessary to duplicate the state inside your child component, you can use the parent's methods directly to manipulate and store input value:
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>
);
}
Ad
source: stackoverflow.com
Related Questions
- → Import statement and Babel
- → should I choose reactjs+f7 or f7+vue.js?
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → .tsx webpack compile fails: Unexpected token <
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → React Native with visual studio 2015 IDE
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM
- → How do I determine if a new ReactJS session and/or Browser session has started?
- → Alt @decorators in React-Native
- → How to dynamically add class to parent div of focused input field?
Ad