Javascript 如何为每个组件提供一个值?
我对本地人的反应有些生疏 我试图为每个组件添加一个值,本质上是登录信息 我正在使用这个库: 您可以通过以下方式获得登录信息:Javascript 如何为每个组件提供一个值?,javascript,reactjs,react-native,Javascript,Reactjs,React Native,我对本地人的反应有些生疏 我试图为每个组件添加一个值,本质上是登录信息 我正在使用这个库: 您可以通过以下方式获得登录信息: import Login from 'react-native-login-keycloak'; const gatheredTokens = await Login.getTokens(); 现在很明显,等待需要在异步函数中,所以我尝试如下: async componentWillMount() { const gatheredTokens = awai
import Login from 'react-native-login-keycloak';
const gatheredTokens = await Login.getTokens();
现在很明显,等待需要在异步函数中,所以我尝试如下:
async componentWillMount() {
const gatheredTokens = await Login.getTokens();
this.setState({ gatheredTokens: this.state.gatheredTokens });
}
然而这看起来很混乱——首先,componentWillMount显然被弃用了(我想我可以改为componentDidMount),而且它还要求我在每个组件中复制这个过程。混乱的代码复制
更纯粹的方法是什么?我猜是沿着高阶组件或其他结构的方向
有人能给我举个例子,说明我将如何向我的所有组件提供此功能(我使用的是Redux,因此通过Redux或其他方法就可以了)-我只是不确定如何确保数据在需要的任何地方都能得到处理和使用,我最想要的是“反应”方式。有多种方法可以做到这一点,渲染道具,高阶组件,甚至挂钩-不确定在我写这个挂钩的时候是否支持React Native 无论如何,既然您建议使用高阶组件,那么我的解决方案将使用高阶组件
export const withGatheredTokens = Component => {
class WithGatheredTokens extends React.Component {
state = { gatheredTokens: null };
async componentDidMount() {
const gatheredTokens = await Login.getTokens();
this.setState({ gatheredTokens });
}
render() {
return (
<Component gatheredTokens={this.state.gatheredTokens} {...props} />
);
}
}
return WithGatheredTokens;
};
// And this is how you use with with a Another Component
export AnotherComponent = withGatheredTokens(AnotherComponentBase)
export const with gatheredtokens=Component=>{
使用GatheredTokens扩展React.Component的类{
state={gatheredTokens:null};
异步组件didmount(){
const gatheredTokens=wait Login.getTokens();
this.setState({gatheredTokens});
}
render(){
返回(
);
}
}
带着收集的票返回;
};
//这就是如何使用另一个组件
导出另一个组件=使用GatheredTokens(另一个组件库)
无论如何,网络请求应该始终在ComponendDupDate中完成,而不是componentWillMount方法。使用Redux
创建您的操作
和还原器
//您可以将您的操作文件命名为loginAction.js
export const setLoginData = data => {
return {
type: SET_LOGIN_TOKEN,
payload: data
}
};
//和你的减速机一样
export default (state = {}, action = {}) => {
switch (action.type) {
case SET_LOGIN_DATA:
return {...state, loginData: action.payload};
default:
return state;
}
}
//别忘了将您的应用商店应用到App.js
包装查看
//
使用
在登录时,当您获得令牌时
async componentDidMount() {
const gatheredTokens = await Login.getTokens();
this.setState({ gatheredTokens: gatheredTokens });
//this.setLoginData(gatheredTokens);
//having imported `setLoginData` from your login action, and also used `mapDispatchToProps`
}
那么你的登录数据应该在你需要的任何地方都可以使用
const mapStateToProps = (state) => ({
loginData: state.loginData,
});
然后,您可以通过以下方式访问loginData中的令牌:
const loginToken = this.props.loginData;
您可以从父组件获取此数据,并将其作为道具传递给每个子组件。如果您使用的是redux,则只需将其设置为中心状态,并将其映射到需要访问数据的任何组件。redux文档中有很多例子:使用redux选择器
mapStateToProps
或将它们作为父组件的道具向下传递。@MattAft-我是在我的store.js中还是在单独的action/reducer中这样做?你能写一个简单的例子吗?我或多或少了解Redux,但我只使用了几个月。如果您希望能够修改状态值,则需要设置操作/缩减器。我提供的链接为您提供了一个简单todo应用程序的示例。问题还在于,如果应用程序关闭以自动登录,您是否希望保存此信息?因为这样您就可以使用RN的异步存储了:您认为这种方法还是HOC方法“更好”呢?我相信两者都可以。这取决于哪个最适合您的用例@CecilRodriguezI相信您的意思是这一行是this.setState({gatheredTokens:gatheredTokens})@塞西尔罗德里格斯是的,是的,我编辑了我的答案。您还可以在这里使用es6速记属性使代码更小(我在编辑中这样做了)@ehab Nice one。我认为这将在某种程度上起作用,对于我进入的每个包含导入组件的屏幕,如果Login.getToken
未完成,它将不断地调用componentDidMount函数again@OluwasayoBabalola否,当安装组件时,只调用componentDidMount一次(除非组件被卸载并再次重新装载)。但是,在获取数据之前,包装好的组件将接收收集到的令牌作为null(我们指定的初始状态),并且一旦获取数据,HigherOrderComponent将重新呈现,并为其子级提供新的值gatheredTokens@ehab对,明白了。componentDidMount只被调用一次。有趣!我们将进一步阅读+1