ipe*_*n67 3 reactjs redux react-hooks
我花了很多时间阅读 React Hooks,虽然它的功能看起来比使用具有本地状态和生命周期方法的类更直观、可读和简洁,但我一直在阅读有关 Hooks 替代 HOCs 的参考资料。
我在 React 应用程序中使用的主要 HOC 是 withAuth —— 基本上是一个检查 currentUser(存储在 Redux 状态)是否经过身份验证的函数,如果是,则呈现包装的组件。
这是一个实现:
import React, { Component } from "react";
import { connect } from "react-redux";
export default function withAuth(ComponentToBeRendered) {
class Authenticate extends Component {
componentWillMount() {
if (this.props.isAuthenticated === false) {
this.props.history.push("/signin");
}
}
componentWillUpdate(nextProps) {
if (nextProps.isAuthenticated === false) {
this.props.history.push("/signin");
}
}
render() {
return <ComponentToBeRendered {...this.props} />;
}
}
function mapStateToProps(state) {
return { isAuthenticated: state.currentUser.isAuthenticated };
}
return connect(mapStateToProps)(Authenticate);
}
Run Code Online (Sandbox Code Playgroud)
我看不到的是如何用钩子替换这个 HOC,特别是因为钩子在调用渲染方法之后才运行。这意味着我将无法在以前是 ProtectedComponent(用 withAuth 包装)上使用钩子来确定是否渲染它,因为它已经被渲染了。
处理此类场景的新奇特钩子方式是什么?
我们可以稍微重新定义“渲染或不渲染”的问题。render 方法将始终在基于钩子的回调或生命周期方法之前被调用。除了一些即将被弃用的生命周期方法之外,这也是成立的。
因此,您的渲染方法(或功能组件)必须处理其所有可能的状态,包括不需要渲染任何内容的状态。要么,要么不渲染任何东西的工作都可以提升到父组件。它的区别在于:
const Child = (props) => props.yes && <div>Hi</div>;
// ...
<Parent>
<Child yes={props.childYes} />
</Parent>
Run Code Online (Sandbox Code Playgroud)
和
const Child = (props) => <div>Hi</div>;
// ...
<Parent>
{props.childYes && <Child />}
</Parent>
Run Code Online (Sandbox Code Playgroud)
决定使用其中的哪一种是视情况而定的。
有很多方法可以使用钩子来解决 HOC 所做的相同问题。我将从 HOC 提供的内容开始;一种访问有关应用程序状态的用户数据的方法,并/signin
在数据表示无效会话时重定向到。我们可以为这两个东西提供钩子。
import { useSelector } from "react-redux";
const mapState = state => ({
isAuthenticated: state.currentUser.isAuthenticated
});
const MySecurePage = props => {
const { isAuthenticated } = useSelector(mapState);
useEffect(
() => {
if (!isAuthenticated) {
history.push("/signin");
}
},
[isAuthenticated]
);
return isAuthenticated && <MyPage {...props} />;
};
Run Code Online (Sandbox Code Playgroud)
在上面的例子中发生了一些事情。我们使用useSelector
钩子 fromreact-redux
来访问状态,就像我们之前使用 using 一样connect
,只是代码少得多。
我们还使用从中获得的值useSelector
来有条件地使用useEffect
钩子触发副作用。默认情况下,我们传递给的回调useEffect
会在每次渲染后调用。但是这里我们还传递了一个依赖项数组,它告诉 React 我们只希望在依赖项更改时触发效果(除了第一次渲染,它总是触发效果)。因此,当isAuthenticated
开始为 false 或变为 false时,我们将被重定向。
虽然这个例子使用了一个组件定义,但这也可以作为一个自定义钩子:
const mapState = state => ({
isAuthenticated: state.currentUser.isAuthenticated
});
const useAuth = () => {
const { isAuthenticated } = useSelector(mapState);
useEffect(
() => {
if (!isAuthenticated) {
history.push("/signin");
}
},
[isAuthenticated]
);
return isAuthenticated;
};
const MySecurePage = (props) => {
return useAuth() && <MyPage {...props} />;
};
Run Code Online (Sandbox Code Playgroud)
最后一件事 - 你可能想知道做这样的事情:
const AuthWrapper = (props) => useAuth() && props.children;
Run Code Online (Sandbox Code Playgroud)
为了能够做这样的事情:
<AuthWrapper>
<Sensitive />
<View />
<Elements />
</AuthWrapper>
Run Code Online (Sandbox Code Playgroud)
您可能会认为最后一个示例适合您,但我会在决定之前阅读此内容。
归档时间: |
|
查看次数: |
3538 次 |
最近记录: |