问题描述:
在使用reducer的用例时传递给子组件,产生的input输入字符的失焦问题。
问题代码
// 2: 组件中使用
const initialState2 = '';
const reducer2 = (state, action) => action;
const [firstName, changeFirstName] = useReducer(reducer2, initialState2);
const [lastName, changeLastName] = useReducer(reducer2, initialState2);
const TextInput = ({ value, onChangeText }) => (
<Input
type="text"
value={value}
onChange={e => onChangeText(e.target.value)}
/>
);
return (
<div>
<div>
First Name:
<TextInput value={firstName} onChangeText={changeFirstName} />
</div>
<div>
Last Name:
<TextInput value={lastName} onChangeText={changeLastName} />
</div>
<div>{testVal}</div>
<div>{firstName}{lastName}</div>
</div>
)
分析
怀疑是onchange的问题,每次数据状态发生变化都会触发render 重写渲染,即视图重写渲染。
于是在外部重新定义了一个组件
import React, { useEffect } from 'react'
import { Button, Input } from 'antd'
export default function MyRenderIpt(props) {
useEffect(() => {
console.log('MyrenderIpt--props', props);
})
return (
<div>
<div style={{ display: 'flex' }}>
MyrenderIpttttt:
<Input
placeholder='MyrenderIpt'
value={props.value}
onChange={e => props.toChangeTest(e.target.value)}
/>
</div>
</div>
)
}
父组件添加以下:
const initStateTest = '';
const reduerTest = (state, action) => action;
const [iptTest, changeIptTest] = useReducer(reduerTest, initStateTest)
<div>
子组件ipt:{iptTest}
<MyRenderIpt value={iptTest} toChangeTest={changeIptTest} />
</div>
结语
发现这个子组件的onchange并没有导致失焦,所以应当是其他地方导致了节点的刷新。
这篇文中 react中因为key值 input自动失去焦点解决 以及文档中对key值的解释:元素的 key 只有放在就近的数组上下文中才有意义。自己这里并没用到循环,应该不存在key值导致的问题。
重新检查一下代码,发现组件嵌套了,应该写在外部的,因为react每次更新数据时会把关联的节点刷新,就导致失焦了。而之前在外部写的组件就没有被刷掉状态,没有失焦。
emmm,下次注意。