在 React 中使用 window.location.reload 是否正确?
Is it correct to use window.location.reload with React?
当你打开reactjs.org,在"Declarative" header下,有一句话:React will efficiently update and render just the right components when your data changes .
对于我的几个应用程序,我使用了以下结构:
应用程序
| AppContainer(所有应用程序逻辑,登录前保护)
|登录(登录表单)
如果您根据用户的凭据 return 应用 render
中的 2 个不同组件,则此结构效果很好。
render(){
if(isUserLoggedIn()){
return <AppContainer />;
}
return <Login />;
}
在 Login
组件中,我使用 window.location.reload
刷新页面,因此应用程序的 render
将被触发,我将获得 AppContainer
组件.
但是感觉有点像jQuery + Angular.有没有更好的(更React的)触发render函数的方式,还是这个事情应该怎样?
Is there a better(more React) way to trigger render function...
通常的方法是拥有状态,在本例中至少是一个布尔值,表示用户是否已登录,并在用户成功登录或注销时更新该状态。更新状态触发渲染。
在你的情况下,因为你使用的是 Redux,你可能在那里有你的状态。
我不使用 Redux(还没有?),这大概是没有它的样子,粗略地(如果你使用的是 class 组件,就像你看起来那样):
class App extends Component {
constructor(props) {
super(props);
this.state = {
loggedIn: /*...initial value, perhaps from web storage or cookie...*/;
};
this.onLogin = this.onLogin.bind(this);
this.onLogout = this.onLogout.bind(this);
}
onLogin() {
// ...probably stuff here, then:
this.setState({loggedIn: true});
}
onLogout() {
// ...probably stuff here, then:
this.setState({loggedIn: false});
}
render() {
if (this.state.logedIn) {
return <AppComponent onLogout={this.onLogout}/>;
}
return <Login onLogin={this.onLogin}/>;
}
}
或带钩子:
const App = () => {
const [loggedIn, setLoggedIn] = useState(/*...initial value, perhaps from web storage or cookie...*/);
const onLogin = useCallback(() => {
// ...probably stuff here, then:
setLoggedIn(true);
}, [loggedIn]);
const onLogout = useCallback(() => {
// ...probably stuff here, then:
setLoggedIn(false);
}, [loggedIn]);
if (this.state.logedIn) {
return <AppComponent onLogout={onLogout}/>;
}
return <Login onLogin={onLogin}/>;
}
(再次,大致)
如果您需要更新组件状态,那么您可以传递一个可观察对象并监听变化或使用一些状态管理库。
这是一种可能的解决方案:
- 创建可观察对象 class
declare type IObserverHandler = (event: any) => void;
export class Observable {
private observers: IObserverHandler[] = [];
public subscribe(observer: IObserverHandler) {
if (!this.observers.includes(observer)) {
this.observers.push(observer);
}
}
public unsubscribe(observer: IObserverHandler) {
this.observers = this.observers.filter(o => o !== observer);
}
public publish(event: any) {
for (const observer of this.observers) {
observer(event);
}
}
}
- 创建登录名 class 以发布有关登录或注销等操作的事件
class Login extends Observable {
public login() {
this.publish({ value: true });
}
public logout() {
this.publish({ value: false });
}
}
- 在组件中订阅观察者并使用事件值更新组件状态
export abstract class Component extends React.Component<any, any> {
private observer: IObserverHandler;
private observable: Login;
constructor(props: any) {
super(props);
this.observable = this.props.observable;
this.state = { isAuthenticated: false }
this.observer = (event) => {
this.setState({ isAuthenticated: event.value })
}
this.observable.subscribe(this.observer);
}
componentWillUnmount() {
this.observable.unsubscribe(this.observer);
}
}
当你打开reactjs.org,在"Declarative" header下,有一句话:React will efficiently update and render just the right components when your data changes .
对于我的几个应用程序,我使用了以下结构: 应用程序 | AppContainer(所有应用程序逻辑,登录前保护) |登录(登录表单)
如果您根据用户的凭据 return 应用 render
中的 2 个不同组件,则此结构效果很好。
render(){
if(isUserLoggedIn()){
return <AppContainer />;
}
return <Login />;
}
在 Login
组件中,我使用 window.location.reload
刷新页面,因此应用程序的 render
将被触发,我将获得 AppContainer
组件.
但是感觉有点像jQuery + Angular.有没有更好的(更React的)触发render函数的方式,还是这个事情应该怎样?
Is there a better(more React) way to trigger render function...
通常的方法是拥有状态,在本例中至少是一个布尔值,表示用户是否已登录,并在用户成功登录或注销时更新该状态。更新状态触发渲染。
在你的情况下,因为你使用的是 Redux,你可能在那里有你的状态。
我不使用 Redux(还没有?),这大概是没有它的样子,粗略地(如果你使用的是 class 组件,就像你看起来那样):
class App extends Component {
constructor(props) {
super(props);
this.state = {
loggedIn: /*...initial value, perhaps from web storage or cookie...*/;
};
this.onLogin = this.onLogin.bind(this);
this.onLogout = this.onLogout.bind(this);
}
onLogin() {
// ...probably stuff here, then:
this.setState({loggedIn: true});
}
onLogout() {
// ...probably stuff here, then:
this.setState({loggedIn: false});
}
render() {
if (this.state.logedIn) {
return <AppComponent onLogout={this.onLogout}/>;
}
return <Login onLogin={this.onLogin}/>;
}
}
或带钩子:
const App = () => {
const [loggedIn, setLoggedIn] = useState(/*...initial value, perhaps from web storage or cookie...*/);
const onLogin = useCallback(() => {
// ...probably stuff here, then:
setLoggedIn(true);
}, [loggedIn]);
const onLogout = useCallback(() => {
// ...probably stuff here, then:
setLoggedIn(false);
}, [loggedIn]);
if (this.state.logedIn) {
return <AppComponent onLogout={onLogout}/>;
}
return <Login onLogin={onLogin}/>;
}
(再次,大致)
如果您需要更新组件状态,那么您可以传递一个可观察对象并监听变化或使用一些状态管理库。
这是一种可能的解决方案:
- 创建可观察对象 class
declare type IObserverHandler = (event: any) => void;
export class Observable {
private observers: IObserverHandler[] = [];
public subscribe(observer: IObserverHandler) {
if (!this.observers.includes(observer)) {
this.observers.push(observer);
}
}
public unsubscribe(observer: IObserverHandler) {
this.observers = this.observers.filter(o => o !== observer);
}
public publish(event: any) {
for (const observer of this.observers) {
observer(event);
}
}
}
- 创建登录名 class 以发布有关登录或注销等操作的事件
class Login extends Observable {
public login() {
this.publish({ value: true });
}
public logout() {
this.publish({ value: false });
}
}
- 在组件中订阅观察者并使用事件值更新组件状态
export abstract class Component extends React.Component<any, any> {
private observer: IObserverHandler;
private observable: Login;
constructor(props: any) {
super(props);
this.observable = this.props.observable;
this.state = { isAuthenticated: false }
this.observer = (event) => {
this.setState({ isAuthenticated: event.value })
}
this.observable.subscribe(this.observer);
}
componentWillUnmount() {
this.observable.unsubscribe(this.observer);
}
}