Javascript 使用useReducer和useContext,在调度操作时不会重新调用组件。如何触发重新加载?

Javascript 使用useReducer和useContext,在调度操作时不会重新调用组件。如何触发重新加载?,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我是React的初学者,正在学习如何与useReducer和useContext一起工作。 我正在研究的一个非常简单的研究示例只是一个名为Greeting的组件,它获取从StateContext传递的状态,它显示Main.js中的用户(Mike)的名称,并且它有一个按钮,该按钮应该发送将名称更改为John的操作。 问题是,当单击按钮时,什么也没有发生,问候语组件中的名称保持不变。 我注意到,一旦发出action changeName,问候组件中的console.log就不会被触发,我相信这意味着

我是React的初学者,正在学习如何与useReducer和useContext一起工作。 我正在研究的一个非常简单的研究示例只是一个名为Greeting的组件,它获取从StateContext传递的状态,它显示Main.js中的用户(Mike)的名称,并且它有一个按钮,该按钮应该发送将名称更改为John的操作。 问题是,当单击按钮时,什么也没有发生,问候语组件中的名称保持不变。 我注意到,一旦发出action changeName,问候组件中的console.log就不会被触发,我相信这意味着问候组件不会被重新提交。 为什么问候语没有重新命名并显示更新的名称

这是主要组件:

import React, { useReducer } from 'react';
import { BrowserRouter, Switch, Route } from 'react-router-dom';

// components
import StateContext from './components/StateContext';
import DispatchContext from './components/DispatchContext';
import Greeting from './components/Greeting';

function reducer(state, action) {
  switch (action.type) {
    case 'changeName':
      const newState = state;
      newState.name = action.name;
      return newState;
    default:
      return;
  }
}

function App() {
  const [state, dispatch] = useReducer(reducer, {
    name: 'Mike',
  });
  console.log('name', state.name);
  return (
    <BrowserRouter>
      <Switch>
        <StateContext.Provider value={state}>
          <DispatchContext.Provider value={dispatch}> 
            <Route path="/greeting">
              <Greeting />
            </Route>
          </DispatchContext.Provider>
        </StateContext.Provider>
      </Switch>
    </BrowserRouter>
  );
}

export default App;
import React, { useContext } from 'react';
import StateContext from './StateContext';
import DispatchContext from './DispatchContext';

const Greeting = () => {
  const state = useContext(StateContext);
  const appDispatch = useContext(DispatchContext);
  console.log('inside greeting component', state.name)

  return (
    <>
      <div>{state.name}</div>
      <button onClick={() => appDispatch({ type: 'changeName', name: 'John' })}>
        Change Name
      </button>
    </>
  );
};

export default Greeting;
 
import { createContext } from 'react';

const DispatchContext = createContext();

export default DispatchContext;
import { createContext } from 'react'

const StateContext = createContext()

export default StateContext
StateContext:

import React, { useReducer } from 'react';
import { BrowserRouter, Switch, Route } from 'react-router-dom';

// components
import StateContext from './components/StateContext';
import DispatchContext from './components/DispatchContext';
import Greeting from './components/Greeting';

function reducer(state, action) {
  switch (action.type) {
    case 'changeName':
      const newState = state;
      newState.name = action.name;
      return newState;
    default:
      return;
  }
}

function App() {
  const [state, dispatch] = useReducer(reducer, {
    name: 'Mike',
  });
  console.log('name', state.name);
  return (
    <BrowserRouter>
      <Switch>
        <StateContext.Provider value={state}>
          <DispatchContext.Provider value={dispatch}> 
            <Route path="/greeting">
              <Greeting />
            </Route>
          </DispatchContext.Provider>
        </StateContext.Provider>
      </Switch>
    </BrowserRouter>
  );
}

export default App;
import React, { useContext } from 'react';
import StateContext from './StateContext';
import DispatchContext from './DispatchContext';

const Greeting = () => {
  const state = useContext(StateContext);
  const appDispatch = useContext(DispatchContext);
  console.log('inside greeting component', state.name)

  return (
    <>
      <div>{state.name}</div>
      <button onClick={() => appDispatch({ type: 'changeName', name: 'John' })}>
        Change Name
      </button>
    </>
  );
};

export default Greeting;
 
import { createContext } from 'react';

const DispatchContext = createContext();

export default DispatchContext;
import { createContext } from 'react'

const StateContext = createContext()

export default StateContext
问题 这里的问题是状态对象变异

function reducer(state, action) {
  switch (action.type) {
    case 'changeName':
      const newState = state;      // <-- newState is reference to state
      newState.name = action.name; // <-- mutation!!
      return newState;             // <-- same state reference
    default:
      return;
  }
}