知识点
- createContext 组件数据传递
- useHistory 路由跳转
- useLocation 钩子返回当前url的Location对象 类似于url
- Redirect 路由重定向
- useState() 状态管理
const [state, setState] = useState(initialState);
在初始化状态下,数组中的获取的state值和传入的initialState值相等的 setState函数用来更新state值,接收一个新的参数更新state值,并重现渲染加入队列。
-
启用状态
-
初始化
-
读取
-
更新
react-router-dom v5.1.0 新增useHistor钩子 hook
正文
父组件
import React , { useContext, createContext, useState } from 'react';
import {
BrowserRouter as Router,
Link,
Route,
Switch,
Redirect,
useHistory,
useLocation
} from 'react-router-dom';
// react-router-dom v5.1.0 新增useHistor钩子 hook
class AuthExample extends React.Component {
render () {
return (
<ProvideAuth>
<Router>
<div>
<AuthButton />
<ul>
<li>
<Link to="/public">Public Page</Link>
</li>
</ul>
<ul>
<li>
<Link to="/protected"> Protected Page</Link>
</li>
</ul>
<Switch>
<Route path="/public">
<PublicPage></PublicPage>
</Route>
<Route path="/login">
<LoginPage></LoginPage>
</Route>
<PrivateRoute path="/protected">
<ProtectedPage></ProtectedPage>
</PrivateRoute>
</Switch>
</div>
</Router>
</ProvideAuth>
)
}
};
AuthButton子组件
根据useAuth返回值,显示是否登陆成功,并改变history路由状态
function AuthButton () {
let history = useHistory();
let auth = useAuth();
console.log(auth);
return auth.user ? (
<p>
Welcome !{''}
<button onClick={ () => { auth.signout (() => history.push('/')); }}>
Sign out
</button>
</p>
) : (
<p>You are not logged in.</p>
)
};
PrivateRoute子组件
- children: 如果用户已经登录显示内容
- location 登陆后的路由信息
- ...rest 扩展运算符 从rest取参数location,判断用户已经登录,显示childern内容,否则重定向到'/login',重新登录,并传值state,内容为location,
// 登陆后显示的内容
function ProtectedPage() {
return <h3>Protected</h3>;
}
function PrivateRoute ( {children ,...rest }) {
let auth = useAuth();
console.log('PrivateRoute组件开始~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~');
console.log(children);
console.log( { ...rest } );
return (
<Route
{ ...rest }
render = { ( { location } ) => auth.user ? ( children ) : (
<Redirect to={{ pathname:"/login",state: { from:location } }} />
) }
></Route>
)
};
LoginPage子组件
- useHistory() 获取 路由信息
- useLocation() 获取location 信息
- useAuth() 获取登录信息
- useLocation 钩子返回当前url的Location对象 类似于url
function LoginPage () {
let history = useHistory();
let location = useLocation();
let auth = useAuth();
console.log(auth);
let { from } = location.state || { from : {pathname:'/'} };
let login = () => {
auth.signin( () => {
history.replace(from);
})
};
return (
<div>
<p>You must log in to view the page at { from.pathname } </p>
<button onClick={ login }> Log in</button>
</div>
)
};
public 子组件
function PublicPage() {
return <h3>Public</h3>;
}
操作
createContext
官网:zh-hans.reactjs.org/docs/contex…
const authContext = createContext();
// 从authContext 中取值
function useAuth () {
return useContext(authContext);
};
ProvideAuth函数
- createContext 父子组件 数据传值 适合于多层嵌套
function ProvideAuth({ children }) {
const auth = useProvideAuth();
console.log(auth);
return (
<authContext.Provider value={auth}>
{/* 在容器中创建, Provider提供者 类似于标记,生产共享数据的地方,在value中定义需要共享的值 */}
{children}
</authContext.Provider>
);
};
fakeAuth函数
初始化登录信息,定义部分变量
const fakeAuth = {
isAuthenticated: false, // 初始化状态值
signin(cb) {
fakeAuth.isAuthenticated = true; // 修改状态值
// 100ms改变路由状态
setTimeout(cb, 100); // fake async
},
signout(cb) {
fakeAuth.isAuthenticated = false; // 修改状态值
// 100ms改变路由状态
setTimeout(cb, 100);
}
};
useProvideAuth函数
- 通过 useState() 更新用户数据,改变登录路由状态
- setUser 操作数据
function useProvideAuth() {
const [user, setUser] = useState(null);
const signin = cb => {
return fakeAuth.signin(() => {
console.log(fakeAuth);
setUser("user");
// 在登陆之后,改变路由状态
cb();
});
};
const signout = cb => {
return fakeAuth.signout(() => {
console.log(fakeAuth);
setUser(null);
// 在登陆之后,置空路由
cb();
});
};
return {
user,
signin,
signout
};
};
react-router-dom 用户是否登录 进行Redirect重定向页面。
日记一日