我对React Native还是比较陌生,并且想建立一个非常简单的身份验证流程。基本逻辑在起作用,我无法处理的是需要更改顶级App.js中状态的“登录”按钮事件:
我有一个顶层App.js,它呈现了一个具有3个可能屏幕的简单Stack Navigator:SplashScreen(直到isLoading状态更改为false),LoginScreen(如果isLoggedIn状态为false)和LaunchScreen(如果isLoggedin状态为真)
根据docs,我运行加载函数,该函数从App.js的componentDidMount()函数中的远程服务器获取用户身份验证数据。无论返回什么结果,它都会将isLoading状态设置为false并将isLoggedIn设置为false设置为true。假设为了简单起见,现在返回1并完成了加载。 isLoggedIn暂时保持为假,因此用户进入登录屏幕。
App.js
import SplashScreen, {myLoadingFunction} from './SplashScreen.js'
// Other imports
const Stack = createStackNavigator()
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoggedIn: false,
isLoading: true
}
}
componentDidMount() {
if (myLoadingFunction () == 1) {
this.setLoadingFinished()
}
}
setLoggedIn = () => (
this.setState({
isLoggedIn: true,
})
)
setLoadingFinished = () => (
this.setState({
isLoading: false
})
)
render() {
// Show SplashScreen while verifying user token
if (this.state.isLoading) return <SplashScreen />
const { contextState } = this.context
return (
<MyProvider>
<NavigationContainer>
<Stack.Navigator>
{contextState.isLoggedIn == true ? (
// User is signed in
<Stack.Screen
name="LaunchScreen"
component={LaunchScreen}
/>
) : (
// No token found, user isn't signed in
<Stack.Screen name="LoginScreen" component={LoginScreen} />
)}
</Stack.Navigator>
</NavigationContainer>
</MyProvider>
);
}
}
App.contextType = MyContext
SplashScreen.js
export const myLoadingFunction = () => {
// fetching some data from server
console.log("Splash Screen loading/fetching data...")
return 1
}
export default class SplashScreen extends React.Component {
render (){
return (
<View>
<Text>Application is being loaded...</Text>
</View>
)
}
}
直到确定可以通过安装App组件后,我将使用一个简单的逻辑(myLoadingFunction)来验证用户是否具有有效的令牌,然后返回一个值。当前,它将isLoading状态更改为false,不更改isLoggedIn状态,因此用户位于登录屏幕上。
LoginScreen.js
export const myFetchUserToken = () => {
console.log("Login Screen fetching data...")
return 1
}
export default class LoginScreen extends React.Component {
render (){
return (
<View>
<Text>You are currently logged out</Text>
<Button title="Log In" onPress={()=>{}}/>
</View>
)
}
}
LoginScreen.contextType = MyContext
单击此按钮时,我只想在App中将isLoggedIn状态更改为true(为了简单起见,现在跳过auth逻辑)。这将触发App中的渲染功能,并向用户显示启动屏幕。我该如何实现?
我尝试过的事情:
MyContext.js
const MyContext = React.createContext({
name: "defName",
age: 0,
setUser: (name) => {},
})
class MyProvider extends React.Component {
// Context state
state = {
name: "stateName",
age: 20,
isLoggedIn:false
}
setUser = (name) => {
this.setState({
name: "changedName"
})
}
setLogInTrue = () => {
this.setState({
isLoggedIn: true
})
}
render() {
const {children} = this.props
return (
<MyContext.Provider
value={{
contextState: this.state,
setUser: this.setUser,
setLogInTrue: this.setLogInTrue
}}
>
{children}
</MyContext.Provider>
)
}
}
export default MyContext
export { MyProvider }
有了Expo,我有了AppEntry.js,可以在其中将应用程序包装到MyContext中:
AppEntry.js
ReactDOM.render(
(
<MyProvider>
<App />
</MyProvider>
),
document.getElementById('root'),
);
这样,我将条件this.state.isLoggedIn == true
更改为contextState.isLoggedIn == true
,现在可以使用了。还向MyContext添加了setLogInTrue()函数(上面已更新),可以在LoginScreen Button中调用它:
更新了LoginScreen.js
export default class LoginScreen extends React.Component {
render (){
const { contextState, setLogInTrue } = this.context
console.log(contextState)
return (
<View>
<Text>You are currently logged out</Text>
<Button title="Launch Application" onPress={setLogInTrue}/>
</View>
)
}
}
LoginScreen.contextType = MyContext
如果我console.log contextState,它现在将isLoggedIn状态更改为true。但是App.js不会重新呈现(“登录屏幕”会根据日志重新呈现)。为什么?
好的,只有一个拼写错误(在上下文状态为loginIn,我更改了isLoggedIn的状态,而不是loggedIn)
如果有人需要,我会将整个代码留在这里。
答案 0 :(得分:0)
尝试在app.js中使用上下文api并在其中设置函数和状态。
示例:- 1:- 写这些行 const defaultValue =更改状态的函数 const MyContext = React.createContext(defaultValue); 2:- 将app.js中的所有组件包装在一起 ...所有组件