Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/446.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 刷新页面时,上下文状态未定义_Javascript_Reactjs_React Hooks_Use Context - Fatal编程技术网

Javascript 刷新页面时,上下文状态未定义

Javascript 刷新页面时,上下文状态未定义,javascript,reactjs,react-hooks,use-context,Javascript,Reactjs,React Hooks,Use Context,我正在创建一个社交媒体应用程序,当我与用户登录时,我会将令牌保存在本地存储中,并将用户信息放入上下文中,以便在几个组件中使用它,然后它会工作,但当我刷新页面时,数据会消失,上下文未定义。我做错了什么 我的App.js function App() { const [userData, setUserData] = useState({ name: "", lastname: "", username: "

我正在创建一个社交媒体应用程序,当我与用户登录时,我会将令牌保存在本地存储中,并将用户信息放入上下文中,以便在几个组件中使用它,然后它会工作,但当我刷新页面时,数据会消失,上下文未定义。我做错了什么

我的App.js

function App() {
   const [userData, setUserData] = useState({
      name: "",
      lastname: "",
      username: "",
      email: "",
   });

   return (
      <Router>
          <userContext.Provider value={{ userData, setUserData }}>
             <div className="app">
             <Switch>
                <Route exact path="/" component={Login} />
                <Route path="/register" component={Register} />
                <Route path="/home" component={Home} />
                <Route path="/profile" component={Profile} />
             </Switch>
             </div>
          </userContext.Provider>
      </Router>
     );
   }
函数应用程序(){
const[userData,setUserData]=useState({
姓名:“,
姓氏:“,
用户名:“”,
电邮:“,
});
返回(
);
}
我的Login.js

function Login() {
const history = useHistory()
const {userData, setUserData} = useContext(userContext)
const [loginUser, setLoginUser] = useState({
    email: '',
    password: ''
})
const [error, setError] = useState()

const {email, password} = loginUser
const handleOnChange = (e) => {
    setLoginUser({ ...loginUser, [e.target.name]: e.target.value})
}

const handleOnSubmit = (e) => {
    e.preventDefault()
    axios.post("http://localhost:5000/login", loginUser)
    .then((res) => {
        setUserData({
            name: res.data.user.name, 
            lastname: res.data.user.lastname, 
            username: res.data.user.username, 
            email: res.data.user.email, 
        })        
        localStorage.setItem("auth-token", res.data.token)
        history.push("/home")   
    })
    .catch(err => {
         err.response.data.msg && setError(err.response.data.msg)
    })  
}  

return (
    <div className="login">
        <div>
            <form onSubmit={handleOnSubmit} className="login-form">
            {error ? <h4 className='login-error'>{error}</h4> : ""}
                <input type="email" placeholder="Email or username" value={email} name='email' onChange={e => handleOnChange(e)}/>
                <input type="password" placeholder="Password" value={password} name='password' onChange={e => handleOnChange(e)}/>
                <Button type="submit" variant="contained">Log in</Button>
                <div></div>
                <p>Don't have an account? <Link to="/register">Click here</Link></p>
            </form>
            <h1>Raise your word <TwitterIcon className="login-right-icon"/></h1> 
        </div>
    </div>
)
}
函数登录(){
const history=useHistory()
const{userData,setUserData}=useContext(userContext)
常量[loginUser,setLoginUser]=useState({
电子邮件:“”,
密码:“”
})
const[error,setError]=useState()
const{email,password}=login用户
常数变化=(e)=>{
setLoginUser({…loginUser[e.target.name]:e.target.value})
}
const handleOnSubmit=(e)=>{
e、 预防默认值()
axios.post(“http://localhost:5000/login“,登录用户)
。然后((res)=>{
setUserData({
名称:res.data.user.name,
lastname:res.data.user.lastname,
用户名:res.data.user.username,
电子邮件:res.data.user.email,
})        
setItem(“auth token”,res.data.token)
历史记录。推送(“/主页”)
})
.catch(错误=>{
err.response.data.msg&&setError(err.response.data.msg)
})  
}  
返回(
{错误?{error}:“}”
更改(e)}/>
更改(e)}/>
登录
没有帐户?请单击此处

说话算数 ) }
My Home.js,如果刷新,则会丢失上下文中的数据

function Home() {
const {userData, setUserData} = useContext(userContext)
const [posts, setPost] = useState([])
const [createPost, setCreatePost] = useState('')
const handleToken = () => {
    localStorage.removeItem('auth-token')
}

const token = localStorage.getItem("auth-token");

const handleOnSubmit = (e) => {
    e.preventDefault()
    axios.post('http://localhost:5000/posts', {textOfThePost: createPost}, {
        headers: { 'auth-token': token },
    })
    .then((res) => {setCreatePost("")})
}

useEffect(() => {
    axios.get('http://localhost:5000/posts')
    .then(res => {
        setPost(res.data)
    })
}, [createPost])

return (
    <div className="home">
        <div style={{display: 'flex', alignItems: 'center'}}>
            <h1>this is the home: Welcome, {userData.username}</h1>
            <Link style={{margin: 10}} to="/home">home</Link>
            <Link style={{margin: 10}} to="/profile">profile</Link>
            <Link style={{margin: 10}} onClick={handleToken} to="/">log out</Link>
        </div>
        <form onSubmit={handleOnSubmit}>
            <input type="text" placeholder="What's happening?" value={createPost} onChange={e => setCreatePost(e.target.value)}/>
            <button type="submit">tweet</button>
        </form>
        <div style={{display: 'flex', flexDirection: 'column'}}>
            {posts.map(post => (
                <div style={{border: '2px solid black', marginBottom: 10, marginRight: 'auto', marginLeft: 'auto', width: 300}} key={post._id}>
                    <div style={{display: 'flex', alignItems: 'center'}}>
                    <Avatar src={post.avatar}/>
                    <span style={{color: 'blue', marginLeft: 10}}>{post.name} <span style={{color: 'grey', fontSize: 11}}>@{post?.username}</span></span><br/>
                    </div>
                    <span>{post.textOfThePost}</span><br/>
                    <span>{moment(post.date).format('lll')}</span>
                </div>
            )).reverse()}
        </div>
    </div>
)
}
函数Home(){
const{userData,setUserData}=useContext(userContext)
const[posts,setPost]=useState([]
常量[createPost,setCreatePost]=useState(“”)
常量handleToken=()=>{
localStorage.removietem('auth-token')
}
const-token=localStorage.getItem(“auth-token”);
const handleOnSubmit=(e)=>{
e、 预防默认值()
轴心柱http://localhost:5000/posts“,{textofpost:createPost}{
标头:{'auth token':token},
})
.然后((res)=>{setCreatePost(“”})
}
useffect(()=>{
axios.get()http://localhost:5000/posts')
。然后(res=>{
setPost(恢复数据)
})
},[createPost])
返回(
这是家:欢迎,{userData.username}
家
轮廓
注销
setCreatePost(e.target.value)}/>
推特
{posts.map(post=>(
{post.name}@{post?.username}
{post.textofpost}
{moment(post.date).format('lll')} )).reverse()} ) }
您只将
令牌
存储在
本地存储
中,因此没有理由同时保存上下文

如果确实要保存
用户数据
,可以将其保存在
本地存储
(或使用任何其他状态管理方式):

函数登录(){
//无关代码
const handleOnSubmit=(e)=>{
e、 预防默认值()
axios.post(“http://localhost:5000/login“,登录用户)
。然后((res)=>{
const{name,lastname,username,email}=res.data.user;
const newUserData={name,lastname,username,email};
setUserData(newUserData);
setItem('user-data',JSON.stringify(newUserData));
//无关代码
}); 
}
//无关代码
}
然后在
App
useState
调用中使用它:

函数应用程序(){
const persistentUserData=localStorage.getItem('user-data');
const[userData,setUserData]=useState(JSON.parse(persistentUserData));
//返回
}

此类JS应用程序中的状态在页面刷新之间不会自动保持。因此需要localstorage/sessionstorage/indexdb和类似的机制。您需要保存状态并在组件加载时检索它

例如,您可以使用如下钩子修改
home
组件以保存/检索数据:

function App() {
   // 1. Create a key to name your data in local storage
   const USER_DATA_KEY_IN_LOCALSTORAGE = 'user_data';
   const [userData, setUserData] = useState({
      name: "",
      lastname: "",
      username: "",
      email: "",
   });

   // 2. Retrieve userData from local storage on startup
   useEffect(() => {
     const userDataString = window.localStorage.getItem(USER_DATA_KEY_IN_LOCALSTORAGE);
     setUserData(JSON.parse(userDataString));
   }, []);

   // 3. Update userData in local storage when it changes.
   useEffect(() => {
     window.localStorage.setItem(USER_DATA_KEY_IN_LOCALSTORAGE, JSON.stringify(userData));
   }, [userData]);

   return (
      <Router>
          <userContext.Provider value={{ userData, setUserData }}>
             <div className="app">
             <Switch>
                <Route exact path="/" component={Login} />
                <Route path="/register" component={Register} />
                <Route path="/home" component={Home} />
                <Route path="/profile" component={Profile} />
             </Switch>
             </div>
          </userContext.Provider>
      </Router>
     );
   }
函数应用程序(){
//1.创建密钥以命名本地存储中的数据
const USER_DATA_KEY_IN_LOCALSTORAGE='USER_DATA';
const[userData,setUserData]=useState({
姓名:“,
姓氏:“,
用户名:“”,
电邮:“,
});
//2.启动时从本地存储中检索用户数据
useffect(()=>{
const userDataString=window.localStorage.getItem(localStorage中的USER\u DATA\u KEY\u);
setUserData(JSON.parse(userDataString));
}, []);
//3.当用户数据发生变化时,更新本地存储中的用户数据。
useffect(()=>{
setItem(USER_DATA_KEY_IN_localStorage,JSON.stringify(userData));
},[userData]);
返回(
);
}

当然,您需要处理用户数据不存在、JSON.parse()抛出错误和类似内容的情况。

非常感谢!我把用户数据放在本地存储之前,似乎我错过了你在app.js中所做的事情。现在它开始工作了