繁体   English   中英

通过获取返回 promise 作为 ReactJS 中的上下文值

[英]Pass fetch returned promise as Context value in ReactJS

我正在尝试将来自助手 function 的获取请求响应传递给 ReactJS 上下文。

这是我的上下文:

const SomeContext = React.createContext();

const SomeProvider = SomeContext.Provider;
const SomeConsumer = SomeContext.Consumer;

export {SomeProvider, SomeConsumer};

这是我的助手 function:

function FetchU() {
  const zx = localStorage.getItem("zx");
  const xx = localStorage.getItem("xx");
  const requestOptions = {
    method: "GET",
    headers: {
      "Content-Type": "application/json",
      Accept: "application/json",
      accesstoken: accessToken,
      userid: userid
    }
  };
  if (userid !== null) {
    fetch(
      process.env.REACT_APP_API_URL + "/authenticated/get-roles",
      requestOptions
    )
      .then(response => response.json())
      .then(response => {
        console.log(response);
      });

  } else {
    console.log("not loggedin === no user permissions.");
  }
}
export default FetchU;

这就是我使用Context Provider的方式

 <PermissionsProvider value="something">
     <Child Component />
     <SecondChild Component />
     <ThirdChild Component />
 </PermissionsProvider>

我的助手 function 由应用程序内部的事件手动触发,因此可以选择value=something实际上可能等于nullundefined

我想将FetchU function 中的值代替value=something 关于如何做到这一点的任何建议?

this.setState({response}) 而不是 (console.log(response))

<PermissionsProvider value={this.state.response}>

我将为您的情况做的是使用 object 作为默认值定义您的上下文

// Context default values.
const Context = React.createContext({
  value: '',
  loading: false,
  updateContext: () => {},
});

然后在Context.Provider之上创建一个 Provider

const ContextProvider = ({ children }) => {
  const [value, setValue] = React.useState('');
  const [loading, setLoading] = React.useState(false);
  const handleUpdateContext = useCallback(async () => {
    // Call your api here
    setLoading(true);
    let newValue;
    try {
      newValue = await mockAPICall();
    } catch (err) {
      // handle err
    } finally {
      setLoading(false);
    }
    // Then update context value with your result.
    setValue(newValue);
  }, []);
  const context = {
    value,
    loading,
    updateContext: handleUpdateContext,
  };
  return (
    <Context.Provider value={context}>
      {/* I usually do this for extra flexibility */}
      {typeof children === 'function' ? children(context) : children}
    </Context.Provider>
  );
}

然后像这样在您的应用程序中使用它

const App = () => {
  return (
    <ContextProvider>
      <div>
        <Context.Consumer>
          {({ value, loading }) => {
            if (loading) return 'Loading...';
            return (
              <label>
                Result in context :
                <pre>
                  {JSON.stringify(value, '\t', '')}
                </pre>
              </label>
            );
          }}
        </Context.Consumer>
        <Context.Consumer>
          {({ updateContext }) => (
            <button onClick={updateContext}>Simulate API Call</button>
          )}
        </Context.Consumer>
      </div>
    </ContextProvider>
  )
}

有一些事情需要考虑,如果操作变得更复杂,也许你可以使用useReducer 如果出现任何 API 错误,您还可以添加error state。

这是我为您准备的工作代码沙箱。

https://codesandbox.io/s/react-context-demo-to1rn?from-embed

希望能帮助到你 !

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM