React Hooks使用带有回调的状态



我正试图找到一种方法来模仿this.setState({},() => {})callback函数,但要使用钩子。

我设法制作了一个模仿useState函数的方法,但返回了一个回调,其中包含更新数据的更改结果。

回调的接收在状态更新后返回,从日志中可以看出,回调的接收仅在console.log("App")出现后返回,其行为类似于将this.statecallback一起使用时的行为。

问题是,在修改后的setStatecallback内部,即使在更新应用程序后调用它,我也看不到状态的更新,也就是说,在它内部,如果我尝试打印它,我看不到更新的状态。

根据你的说法,有一个解决方案可以做一些事情来看到它的更新。

const { useState, useRef, useEffect } = React;
function useStateCallback(initialState) {
const [state, setState] = useState(initialState);
const cbRef = useRef(null);
useEffect(() => {
if (cbRef.current) {
cbRef.current(state);
cbRef.current = null;
}
}, [state]);
return [
state,
(value, cb) => {
cbRef.current = typeof cb === "function" ? cb : null;
setState(value);
}
];
}
const App =() => {
const [stateObj, setStateObj] = useStateCallback({
name: "James",
surname: "Bond",
number: 7
});
const { name, surname, number } = stateObj;
useEffect(() => {
//console.log("componentDidMount", stateObj);
//console.log("componentDidMount2", stateObj);
//console.log("useEffect", stateObj);
}, []);
const change = () => {
//console.log("componentDidMount", stateObj);
setStateObj(
previousValue => ({
...previousValue,
name: "Arthur",
surname: "Conan",
number: previousValue.number + 14
}),
res => {
console.log("Res:", res, stateObj);
}
);
//console.log("componentDidMount2", stateObj);
};
console.log("App", stateObj);
return (
<div>
Name: {name}
<br />
Surname: {surname}
<br />
Number: {number}
<br />
<button onClick={change}>Change</button>
<button onClick={() => console.log(stateObj)}>Render</button>
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>

使用钩子,当状态更新时,已经得到回调:您的组件函数再次被调用。这是钩子的一个基本方面,更新状态会使React再次调用您的组件函数。

示例:

const { useState } = React;
const Example = () => {
const [counter, setCounter] = useState(0);
console.log(`Example called, counter = ${counter}`);
return (
<div>
{counter} <input type="button" value="+" onClick={() => setCounter(c => c + 1)} />
</div>
);
};
ReactDOM.render(<Example />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.11.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script>

不需要任何其他的setter回调。组件回调。

丹·阿布拉莫夫(Dan Abramov(有一篇很好的文章,在这里真的很震撼。这是在解释useEffect的背景下进行的,但它所奠定的基础应该会有所帮助。

如果我理解您试图正确执行的操作,我认为您只需要将新的状态值作为参数传递给回调调用。这样,您就不需要将其保存在ref中,也不需要从useEffect:更新它

function useStateCallback(initialState) {
const [state, setState] = useState(initialState);
return [
state,
(value, callback) => {
setState(value);
if (typeof callback === "function") {
callback(value);
}
}
];
}

相关内容

  • 没有找到相关文章

最新更新