我注意到我的代码中有一些东西,我只是想在这里确认一下。 (使用 Redux 和 React)
假设我有一个按钮,当你点击它时,这个函数被调用:
onClick={ () => {
updateSomeVar(10);
console.log(someVar);
}}
其中 updateValue()
分派了一个将存储中 someVar
的值更新为 10 的操作。
但是,在下面的 console.log
中,它仍然打印旧值 someVar
,而不是 10
。
是不是因为 console.log
在 store 更新触发 React 组件重新渲染之前运行,这就是为什么我们仍然看到旧值? (组件重新渲染后,值确实是10
)。
我只是认为 Redux 操作是同步的,所以我希望 console.log
具有最新的值?
答案 0 :(得分:1)
是的,除非您使用像 synchronous
这样的中间件,否则默认情况下状态更新为 thunk
。
这里发生的事情是,您在调用重新渲染组件的 updateSomeVar
之后记录值。
每个渲染都有自己的一组值。通过对 setTimeout
使用 console.log
来观察此行为。它仍然会打印旧值。
这是因为组件根据当前闭包使用状态值,因此,当闭包更新时(组件重新渲染时会发生这种情况),状态值将被反映。
这样看,这里是一个非常简单的 React 钩子和状态更新的实现。
let React = (function() {
let global = {}; // define a global variable where we store information about the component
let index = 0; // index to keep track of the component's state
function render(Component) {
global.Component = Component;
const instance = Component(); // get the instance of the component
index = 0;
instance.render(); // call the component's render function
global.instance = instance; // store the component's instance for any future calls of the component's functions
return global; // return the global variable
}
function useState(initialState) {
if (!global) {
throw new Error("Need a global");
}
if (!global.hooks) {
global.hooks = []; // this array holds the state of the component
}
const hooks = global.hooks;
const currentState = global.hooks[index] || initialState;
hooks[index] = currentState; // memoize the state for future access
const setState = (function() {
let currentIndex = index; // copy the index so each useState call will have it's own "closed" value over index (currentIndex)
return function(value) {
global.hooks[currentIndex] = value;
render(global.Component); //re-render the component after state change
};
})();
index = index + 1;
return [currentState, setState];
}
return { render, useState, useEffect };
})();
function Component() {
// Component is called at each re-render. index is reset to 0.
const [count, setCount] = React.useState(0);
// hooks: [0], currentIndex: 0, Incremented Index: 1
const [word, setWord] = React.useState("");
// hooks: [0, ''], currentIndex: 1, Incremented Index: 2
const countSetter = () => {
setCount(count + 1);
};
const wordSetter = word => {
setWord(word);
};
function render() {
console.log(`Count is: ${count}, Word is: ${word}`);
}
return { render, countSetter, wordSetter };
}
const global = React.render(Component); // hooks: [ 0, '', [ 0, '' ], [] ]
global.instance.countSetter(); // hooks: [ 1, '', [ 1, '' ], [] ]
global.instance.countSetter(); // hooks: hooks: [ 2, '', [ 2, '' ], [] ]
global.instance.countSetter(); // hooks: [ 3, '', [ 3, '' ], [] ]
global.instance.wordSetter("yooo"); // hooks: [ 3, 'yooo', [ 3, 'yooo' ], [] ]
global.instance.wordSetter("ssup"); // hooks: [ 3, 'yooo', [ 3, 'yooo' ], [] ]
您的 console.log
关闭了当前渲染的状态变量的值,因此,它返回该特定渲染拥有的值。
通过回顾上面的实现,当组件重新渲染时,索引会被更新,只有这样,新的值才会对组件可用。
这是解释概念的实现链接:
Github 链接:https://github.com/rohitpotato/implement-react-hooks