React with Hooks 中的两种数据绑定方式
Two way data binding in React with Hooks
我正在使用 React 构建一个应用程序,其中两个组件应该能够改变彼此的状态:
组件 A -> 组件 B
组件 B -> 组件 A
组件 A 是一组按钮,组件 B 是输入元素。
我设法让它只以一种方式工作,A -> B 或只是 B -> A,但不能同时工作。它在使用 useEffect 钩子时部分起作用,但有错误,我认为这真是愚蠢的想法。
我读过很多关于 React 不能以这种方式工作的文章,但是有什么迂回的方法可以让它工作吗?我的应用程序确实需要这种双向数据绑定。
感谢您的帮助!
按钮的状态位于自定义上下文挂钩 (useStateContext) 中的 digits 变量数组中。
import { useStateContext } from "components/StateProvider/Context";
import { useState, useEffect } from "react";
import { baseConvert } from "utility/baseConvert";
const NumberInput = () => {
const [ { digits, baseIn, baseOut }, dispatch ] = useStateContext();
const convertedValue = baseConvert({
digits,
baseIn,
baseOut
});
const [ inputValue, setInputValue ] = useState(convertedValue);
/* useEffect(() => {
setInputValue(convertedValue)
}, [ digits, baseIn, baseOut ]) */
const regex = /^[A-Z\d]+$/;
const handleInput = ({ target: { value }}) => {
if (value === "") setInputValue(0);
console.log(value);
if (regex.test(value)) {
setInputValue(value);
dispatch({
type: "setDigits",
digits: baseConvert({
digits: value.split("").map(Number),
baseIn: baseOut,
baseOut: baseIn
})
})
}
};
return (
<input type="text" onChange={handleInput} value={inputValue} />
);
};
export default NumberInput;
组件不应该直接操作其他组件的状态。如果您需要共享数据,将状态带到父组件并将回调传递给可以更改状态的子组件。
例如:
function ParentComponent() {
const [currentVal, setCurrentVal] = useState(0);
return
<>
<Child1 value={currentVal} onChange={setCurrentVal}/> // you might also pass a function that does some other logic and then calls setCurrentVal
<Child2 value={currentVal} onChange={setCurrentVal}/>
</>
}
@Jeff Storey
解决方案似乎有点不对。第一个索引是值,第二个索引是更新值的函数。
应该是:
const [currentVal, setCurrentVal] = useState(0);
我正在使用 React 构建一个应用程序,其中两个组件应该能够改变彼此的状态:
组件 A -> 组件 B
组件 B -> 组件 A
组件 A 是一组按钮,组件 B 是输入元素。
我设法让它只以一种方式工作,A -> B 或只是 B -> A,但不能同时工作。它在使用 useEffect 钩子时部分起作用,但有错误,我认为这真是愚蠢的想法。
我读过很多关于 React 不能以这种方式工作的文章,但是有什么迂回的方法可以让它工作吗?我的应用程序确实需要这种双向数据绑定。
感谢您的帮助!
按钮的状态位于自定义上下文挂钩 (useStateContext) 中的 digits 变量数组中。
import { useStateContext } from "components/StateProvider/Context";
import { useState, useEffect } from "react";
import { baseConvert } from "utility/baseConvert";
const NumberInput = () => {
const [ { digits, baseIn, baseOut }, dispatch ] = useStateContext();
const convertedValue = baseConvert({
digits,
baseIn,
baseOut
});
const [ inputValue, setInputValue ] = useState(convertedValue);
/* useEffect(() => {
setInputValue(convertedValue)
}, [ digits, baseIn, baseOut ]) */
const regex = /^[A-Z\d]+$/;
const handleInput = ({ target: { value }}) => {
if (value === "") setInputValue(0);
console.log(value);
if (regex.test(value)) {
setInputValue(value);
dispatch({
type: "setDigits",
digits: baseConvert({
digits: value.split("").map(Number),
baseIn: baseOut,
baseOut: baseIn
})
})
}
};
return (
<input type="text" onChange={handleInput} value={inputValue} />
);
};
export default NumberInput;
组件不应该直接操作其他组件的状态。如果您需要共享数据,将状态带到父组件并将回调传递给可以更改状态的子组件。
例如:
function ParentComponent() {
const [currentVal, setCurrentVal] = useState(0);
return
<>
<Child1 value={currentVal} onChange={setCurrentVal}/> // you might also pass a function that does some other logic and then calls setCurrentVal
<Child2 value={currentVal} onChange={setCurrentVal}/>
</>
}
@Jeff Storey 解决方案似乎有点不对。第一个索引是值,第二个索引是更新值的函数。
应该是:
const [currentVal, setCurrentVal] = useState(0);