【问题标题】:Is it possible to update a context state outside of a react component?是否可以在反应组件之外更新上下文状态?
【发布时间】:2020-05-16 02:44:14
【问题描述】:

在 react 项目中,有一个全局可用的警报和消息上下文。在任何给定的组件中,我都可以使用 context.setAlert() 来发送消息。

我将一些 API 获取逻辑提取到实用程序函数中。它不是一个组件。组件在渲染之前以各种方式导入和使用这个函数,有点像这样:

//MyComponent.js
import {fetchFromApi} from "../util"
import AlertContext from "../contexts/alert"

const MyComponent = () => {
  const alertContext = useContext(AlertContext)
  useEffect(() => 
    fetchFromApi(...)
      .then(() => alertContext.setAlert('All set'), [])
  return <Something/>
}

所以在 fetchFromApi 中,我希望能够使用该 AlertContext.setAlert 方法。像这样的:

// util.js
export const fetchFromApi = (params) => 
  fetch("...")
    .then(something)
    .then(somethingelse)
    .then(response => {
      // set alert from the AlertContext is what I want to access
      if (response.status === 500) alertContext.setAlert('oh no')
      return response
    })

我不确定是否/如何更新组件外部的上下文状态。这可能吗?

【问题讨论】:

    标签: reactjs react-context


    【解决方案1】:

    修改 fetchFromApi 的代码,使其采用带有回调函数的附加参数配置。您可以相应地调用回调。

    希望对您有所帮助。

    【讨论】:

    • 谢谢。我想避免这样做,因为每次调用 fetchFromApi 时我都需要这样做,因为行为总是相同的。
    【解决方案2】:

    您可以改变对象并在上下文提供程序中设置 setAlert 属性。这个对象可以被 fetchApi 使用。我假设 fetchApi 仅从 Alert 上下文中的组件调用,因此当 fetchApi 在对象中使用 setAlert 时可以保证设置它:

    const passSetAlert = { setAlert: (x) => x };
    const AlertContext = React.createContext();// mutate passSetAlert
    function AlertProvider(props) {
      const [alert, setAlert] = React.useState('AA');
      passSetAlert.setAlert = setAlert;
      return (
        <AlertContext.Provider value={{ alert, setAlert }}>
          {props.children}
        </AlertContext.Provider>
      );
    }
    const fetchFromApi = (message) =>
      setTimeout(() => {
        passSetAlert.setAlert(message);
      }, 2000);
    
    function App() {
      const [count, setCount] = React.useState(0);
      const alertContext = React.useContext(AlertContext);
      const click = () => {
        const newCount = count + 1;
        setCount(newCount);
        fetchFromApi(newCount);
      };
      return (
        <div>
          <button onClick={click}>change alert</button>
          Alert is: {alertContext.alert}
        </div>
      );
    }
    ReactDOM.render(
      <AlertProvider>
        <App />
      </AlertProvider>,
      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>

    【讨论】:

      猜你喜欢
      • 2021-09-18
      • 1970-01-01
      • 2020-01-01
      • 2019-12-20
      • 1970-01-01
      • 2019-07-27
      • 1970-01-01
      • 2020-08-01
      • 2016-01-19
      相关资源
      最近更新 更多