【问题标题】:reducer function is being called twice减速器函数被调用两次
【发布时间】:2020-04-01 02:15:17
【问题描述】:

我正在练习 React 钩子,但遇到了 useReducer 和 dispatch 函数的问题。当我在第二次点击任一按钮时,我创建的 reducer 函数被调用了两次。我的控制台日志输出在第一次单击任一按钮时打印一次,然后在每次按下按钮时打印两次。

这是我的文件:

Utils.js

import React, {createContext, useReducer, useContext} from 'react';

const initialState = {

    text: 0
}

const StoreContext = createContext(initialState);

const reducer = (state, action) => {
    console.log('hello');

    switch(action.type) {
        case 'add-counter': return {
            ...state,
            text: state.text + 1
        }
        default:
            throw new Error();
    }
}

export const StoreProvider = ({children}) => {
    const [state, dispatch] = useReducer(reducer, initialState);
    return (
        <StoreContext.Provider value={{state, dispatch}}>
            {children}
        </StoreContext.Provider>
    )
}

export const useStore = (store) => {
    const {state, dispatch} = useContext(StoreContext);
    return {state, dispatch};
}

用户列表.js

import React, {useCallback} from 'react';
import { Row, Col, Button } from 'antd';
import TextDisplayComponent from './TextDisplay';
import {useStore} from '../util';

function ListComponent() {
    const {dispatch} = useStore();
    const increment = useCallback(() => dispatch({type: 'add-counter'}), [dispatch])

    return (
        <Row>
            <Col span={12} style={{textAlign: 'center'}}>
                <Button type="primary" onClick={increment}>Press Me</Button>
            </Col>
            <Col span={12} style={{textAlign: 'center'}}>
                <TextDisplayComponent />
            </Col>
        </Row>
    )
}

export default ListComponent;

TextDisplay.js

import React, {useCallback} from 'react';
import {Button} from 'antd'
import {useStore} from '../util'

function TextDisplayComponent() {
    const {state, dispatch} = useStore();
    const increment = useCallback(() => dispatch({type: 'add-counter'}), [dispatch])

    return (
        <div>
            {state.text}
            <Button onClick={increment}>Add</Button>
        </div>
    )
}

export default TextDisplayComponent

App.js

import React from 'react';
import UserListComponent from './components/UserList';
import 'antd/dist/antd.css';
import {StoreProvider} from './util';

function App() {

  React.createContext()
  return (
    <StoreProvider>
      <div className="App">
        <UserListComponent />
      </div>
    </StoreProvider>
  );
}

export default App;

有人可以帮忙吗?谢谢。

完整的测试项目可以在https://github.com/Saro-DA/my-app.git找到

【问题讨论】:

    标签: javascript reactjs react-hooks use-reducer


    【解决方案1】:

    这是故意的。您将应用程序包装在 &lt;React.StrictMode&gt; 中,这将导致在开发模式下发生这种情况。

    请查看this:

    React Strict Mode 做的另一件事是运行确定 回调/方法两次(仅在 DEV 模式下)。你没看错!这 以下回调/方法将在严格模式下运行两次(在 DEV 仅模式)

    【讨论】:

    • 感谢您的回答!我在生产模式下尝试过,这并没有像你提到的那样发生。再次感谢!
    • 感谢您提供的信息,我遇到了完全相同的问题!但是,我不清楚一件事:如果您将 console.log 放入 reducer,则日志始终只执行一次。一个代码块运行两次但只有一个控制台日志是如何工作的?
    • @Stiegi 我也有同样的担忧:/ 但我发现这个链接:github.com/facebook/react/issues/16295#issuecomment-518318185 似乎是正确的行为。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-03
    • 2013-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-12
    • 2015-01-11
    相关资源
    最近更新 更多