Reactjs 如何使用React.createContext包装器在我的特殊情况下执行此Redux Thunk操作创建者
我学习React Redux和Thunk,我需要这个动作创建者使用上下文 我有一个Redux操作Reactjs 如何使用React.createContext包装器在我的特殊情况下执行此Redux Thunk操作创建者,reactjs,redux,Reactjs,Redux,我学习React Redux和Thunk,我需要这个动作创建者使用上下文 我有一个Redux操作asyncSaveUser,它的工作原理如下: const asyncSaveUser = () => { return async dispatch => { dispatch(saveUserStart()); ....Do lots of stuff... }; export default asyncSaveUser; 但我需要它看起来像
asyncSaveUser
,它的工作原理如下:
const asyncSaveUser = () => {
return async dispatch => {
dispatch(saveUserStart());
....Do lots of stuff...
};
export default asyncSaveUser;
但我需要它看起来像这样:(Wrappen在中使用Firebase
)
但当我这样做时,Redux Thunk不会检测到asyncSaveUser
是动作创建者,也不会调用它`
Firebase的上下文:
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;
因此,只有一个新的Firebase()
类。可以说是辛格尔顿风格!。
因此,访问它的唯一方法是通过withFirebase(asyncSaveUser)
我知道我的问题来自于用Firebase将操作包装在中,因此asyncSaveUser
Thunk不再是Thunk
那么,我如何访问我的Firebase
提供商
?我必须从头开始重新设计吗
更新
我已经尝试了以下代码,它一直运行良好:
使用Firebase返回(保存)代码>之后,在save()
中不会命中断点。我看起来像是返回了一个const save=({…
对象,但是它里面的代码没有运行,所以这可能就是它不工作的原因
const asynsaveUser = () => {
return dispatch => {
const save = ({ firestore }) => {
const userRef = firestore.userDoc(firestore.auth.currentUser.uid);
dispatch(saveUserStart());
firestore.db
.runTransaction(transaction => {
// This code may get re-run multiple times if there are conflicts.
return transaction.get(userRef).then(doc => {
if (!doc.exists) {
return Promise.reject('Transaction failed: User dont exist!');
}
const newRoles = doc.data().roles;
// new roll
newRoles.push(ROLES.USER);
// remove roll
newRoles.splice(newRoles.indexOf('ANONYMOUS'), 1);
// save it back
transaction.update(userRef, { roles: newRoles });
return newRoles;
});
})
.then(newRoles => {
dispatch(saveUserSuccess(firestore.auth.currentUser));
console.log(`Transaction successfully committed role(s): ${newRoles}`);
})
.catch(error => {
dispatch(saveUserFailure(error));
console.log(error);
});
};
return withFirebase(save);
};
};
export default asynsaveUser ;
我在这张图片中将asynSaveUser
重命名为saveUser
希望您能理解,请给出建议?问题是,我不明白,当您使用Redux-Action和Redux-Reducer类型的方法时,为什么需要上下文提供者和上下文使用者方法
此外,还有一些错误。
我注意到的第一件事是:
高阶组件在其参数中需要一个组件,而不是动作创建者
高阶组件向组件添加额外属性(Reactprops
)
您在这里试图实现的目标已经由react redux
npm包提供的connect
HOC完成
export const asyncSaveUser=({firestore})=>dispatch=>{
const userRef=firestore.userDoc
...
//不要用Firebase做任何退货
//只需分派此操作创建者必须执行的相应操作
//也就是说,不再需要return语句,除非您想退出执行
//这个功能的
//例如:
调度({你好:'你好',很好:'相同'});
}
现在,在您的index.js
或App.js
文件中,或您要求react
调用您的react
应用程序的任何位置
你只需要这个
现在假设您有一个组件Hello.js
从“React”导入React
从“/firebase”导入{firestore};
从'react redux'导入{connect};
从“../../redux/actionCreators/asyncSaveUser.js”导入{asyncSaveUser};
功能你好(道具){
返回(props.asyncSaveUser({firestore}}>Hello);
}
常量mapStateToProps=(状态)=>{
返回{};
}
const mapDispatchToProps=(调度)=>{
返回{
asyncSaveUser:(stuff)=>dispatch(asyncSaveUser(stuff)),
}
}
导出默认连接(mapStateToProps、mapDispatchToProps)(您好);
问题是你可以制作一个只向你的组件添加firebase
道具的HOC,在这个HOC中,你仍然会使用react redux
中的connect
函数,所以…,制作它并没有什么意义,因为它会在你的组件树中添加不必要的组件,并阻碍性能曼斯
希望这是有意义的,或者是有价值的。Uhmm,我不确定,但是您刚刚在一个更高阶的组件中传递了一个action creator。您应该首先将您的asyncSaveUser
操作放在上下文中。并且您应该导出默认asyncSaveUser
React.createContext({asyncSaveUser})
然后使用创建的上下文。不确定如何执行该操作,“您应该首先将asyncSaveUser操作放在上下文中。”.通常使用HOC是直接的,只是包装它们,而不是这个time@RishabhAnand如果您有时间,可以创建并回答解释此问题吗?我用更多的代码和文本更新了我的问题。感谢好主意,我学到了很多。因为我用Firebase将此新Firebase()
Singelton样式烘焙到我的中(保存)
wrapper HOC所以我不想props.asyncSaveUser({firestore})
无论如何,我在这里等待答案时最后做的是使用Thunk和extraargument
像这样const middleware=[Thunk.withExtraArgument(firebase),initialiseagamiddleware]当我为唯一的新Firebase()
创建React.createContext时,我会在App root中这样做。不知道这是好是坏,也许我会运行一些测试
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'),
);
const asynsaveUser = () => {
return dispatch => {
const save = ({ firestore }) => {
const userRef = firestore.userDoc(firestore.auth.currentUser.uid);
dispatch(saveUserStart());
firestore.db
.runTransaction(transaction => {
// This code may get re-run multiple times if there are conflicts.
return transaction.get(userRef).then(doc => {
if (!doc.exists) {
return Promise.reject('Transaction failed: User dont exist!');
}
const newRoles = doc.data().roles;
// new roll
newRoles.push(ROLES.USER);
// remove roll
newRoles.splice(newRoles.indexOf('ANONYMOUS'), 1);
// save it back
transaction.update(userRef, { roles: newRoles });
return newRoles;
});
})
.then(newRoles => {
dispatch(saveUserSuccess(firestore.auth.currentUser));
console.log(`Transaction successfully committed role(s): ${newRoles}`);
})
.catch(error => {
dispatch(saveUserFailure(error));
console.log(error);
});
};
return withFirebase(save);
};
};
export default asynsaveUser ;