我试图用ExtraArgument将React.createContext Api注入Thunk但不了解

问题描述

我是React学习的新手,现在我有这个Redux Thunk,需要将这个firebase上下文注入其中。

FirebaseContext上下文:
(它还会创建一个与Rect.Componets一起使用的withFirebase。)

    import React from 'react';
    
    const FirebaseContext = React.createContext(null);
    
    export const withFirebase = Component => props => (
        <FirebaseContext.Consumer>{firebase => <Component {...props} firebase={firebase} />}</FirebaseContext.Consumer>
    );

export default FirebaseContext;

这是FirebaseContext.Provider的分配方式:

import Firebase,{ FirebaseContext } from './firebase';
import store from './redux/store';

ReactDOM.render(
    <FirebaseContext.Provider value={new Firebase()}>
        <Provider store={store}>
            <App />
        </Provider>
    </FirebaseContext.Provider>,document.getElementById('root'),);

然后创建Redux存储库,就像下面的标准过程一样注入它:

thunk.withExtraArgument(FirebaseContext),

这是我的Redux Thunk,运行它时会调用Thunk,但是FirebaseContext必须是value={new Firebase()} value,但不知道该怎么做小时,并尝试使用withFirebase将Thunk包裹起来,但Thunk不喜欢这样!

function doSomeWork() {
    return (dispatch,FirebaseContext) => {
        function work() {
            const firebase = FirebaseContext; // HERE IS THE PROBLEM 
            const userRef = firebase.userDoc(firebase.auth.currentUser.uid);
            dispatch(doSomeWorkStart());
            .....
        }
        return work;
    };
}

如何将new Firebase()的“值”传递到Thunk中?

解决方法

编辑:

选项1:

我认为,与其尝试将FirebaseContext传递给您的thunk,不如将其传递给Firebase对象本身。您不能在thunk内部使用上下文,因此要么需要将上下文值作为参数从组件传递到thunk,要么在配置存储区时简单地提供它。

import Firebase,{ FirebaseContext } from './firebase';
import reducer from './redux/reducer';

const firebase = new Firebase();
const store = createStore(
  reducer,applyMiddleware(thunk.withExtraArgument(firebase)),);

ReactDOM.render(
  <FirebaseContext.Provider value={firebase}>
    <Provider store={store}>
      <App />
    </Provider>
  </FirebaseContext.Provider>,document.getElementById('root')
);

此外,您仍然需要更正参数中的参数顺序。 Redux-thunk将按dispatch,getState,firebase的顺序调用您的函数。即使您没有使用getState,也无法忽略它。它仍然会作为参数传递给您的重击。

function doSomeWork() {
  return (dispatch,firebase) => {
    function work() {
      const userRef = firebase.userDoc(firebase.auth.currentUser.uid);
      dispatch(doSomeWorkStart());
    }
    return work;
  };
}

选项2:

如上所述,另一种选择是访问组件内部的上下文,并将其作为参数传递给动作创建者。

function doSomeWork(firebase) {
  return (dispatch,getState) => {
    function work() {
      const userRef = firebase.userDoc(firebase.auth.currentUser.uid);
      dispatch(doSomeWorkStart());
    }
    return work;
  };
}
function MyComponent(props) {
  const dispatch = useDispatch();
  const firebase = useContext(FirebaseContext);

  useEffect(() => {
    dispatch(doSomwWork(firebase))
  },[])

  return <></>;
}

但是,我认为第一个选择是最好的选择。