在 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}/>;
}

(再次,大致)

如果您需要更新组件状态,那么您可以传递一个可观察对象并监听变化或使用一些状态管理库。

这是一种可能的解决方案:

  1. 创建可观察对象 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);
        }
    }
}
  1. 创建登录名 class 以发布有关登录或注销等操作的事件
class Login extends Observable {

    public login() {
        this.publish({ value: true });
    }

    public logout() {
        this.publish({ value: false });
    }
}
  1. 在组件中订阅观察者并使用事件值更新组件状态
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);
    }
}