使用上下文 API 不从全局状态呈现的 React 组件

React components not rendering from global state using context API

我正在尝试让我的子组件查找全局状态。截至目前,我可以注销我的全局状态,我可以看到它已经更新,但我的组件没有更新新值。我没有收到任何错误,但也很难找到一个好的解决方案。如果对这里有帮助,我有完整的回购协议(非常小,只有 1 个组件):https://github.com/jaysnel/context-api-react

我的 ChangeColor.js 文件没有随着新的状态变化而更新有什么原因吗?

UpdateColor.js

import React, { useReducer, useEffect } from 'react'
import { useAppContext } from '../public/context/context'

export default function UpdateColor() {
    let { myGlobaData } = useAppContext();
    const [state, dispatch] = useReducer(reducer, myGlobaData);


    function reducer(state, action) {
        let newState = state.slice();
        console.log(state);
        if(newState !== undefined) {
            switch(action.type) {
                case 'UPDATE_COLOR':
                    newState[0].color = 'green';
                    return newState;
                default:
                    throw new Error();
            }
        }
    }

    return (
        <div>
            <button onClick={() => dispatch({type: 'UPDATE_COLOR'})}>Update Color</button>
        </div>
    )
}

ChangeColor.js

import React from 'react'
import { useAppContext } from '../public/context/context'

export default function ChangeColor() {

    const { myGlobaData } = useAppContext();
    console.log("ChangeColor.js", myGlobaData)

    return (
        <div>
            <h2 style={{color: myGlobaData[0].color}}>I Change Colors Based On Global State.</h2>
        </div>
    )
}

context.js

import { createContext, useContext } from 'react';


const AppContext = createContext();

export function AppWrapper({ children }) {
    const state = {
      myGlobaData: [
            {
                color: 'red',
                text: 'new text new me'
            }
      ],
    }


    return (
      <AppContext.Provider value={state}>
        {children}
      </AppContext.Provider>
    );
  }
  
  export function useAppContext() {
    return useContext(AppContext);
  }
  

我想,你的问题是你在哪里使用了reducer。组件 ChangeColor.js 不知道你在 UpdateColor.js 里面做什么。解决方案是,如果将 reducer 放入全局上下文 context.js,然后您必须在全局范围内访问您的 reducer。 我确实使用两种不同的方法创建并推送到 github 工作示例来使用 actions reducer。 working example

UpdateColor.js

import { useAppContext  } from '../public/context/context'

export default function UpdateColor() {
  const { dispatch } = useAppContext();

  const withPayload = () => {
     dispatch({
       type: 'UPDATE_COLOR_WITH_PAYLOAD',
       payload: {color: 'blue', text: 'new text from updateColor.js'}})
  }
  const intoReducer = () => {
     dispatch({type: 'UPDATE_COLOR_INTO_REDUCER'})
  }

  return (
    <div>
      <button onClick={withPayload}>Update Color with payload</button>
      <button onClick={intoReducer}>Update Color into reducer</button>
    </div>
  )
}

ChangeColor.js

import { useAppContext } from '../public/context/context'

export default function ChangeColor() {
  const { state } = useAppContext();

  return (
    <div>
      <h2 style={{color: state.color}}>I Change Colors Based On Global State.</h2>
      <p style={{textAlign: 'center'}}>{state.text}</p>
    </div>
  )   
}

context.js

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

const AppContext = createContext();

export function useAppContext() {
  return useContext(AppContext);
}

function reducer(state, action) {
  switch (action.type) {
    case 'UPDATE_COLOR_WITH_PAYLOAD':
      return action.payload;
    case 'UPDATE_COLOR_INTO_REDUCER':
      action.color = 'green';
      action.text = 'new text from reducer';
      return action;
   default:
     return state;
  }
}

export function AppWrapper({ children }) {
   const initialState = { color: 'red', text: 'new text new me' };
   const [state, dispatch] = useReducer(reducer, initialState);
   return (
     <AppContext.Provider value={{ state, dispatch }}>
      {children}
     </AppContext.Provider>
   );
}