1

这是我的情况,我对 react/flux 很陌生,刚刚开始玩弄它。我的玩具项目是一个简单的图书馆应用程序。我目前的状态如下:

  • 我有一个名为登录的组件。该组件仅负责存储当前“登录”的用户,以便能够处理库中后面的借/还按钮。因此,用户输入它的名称,该名称将被保存到会话存储中。
  • 我的另一个组件称为库,它包含我的应用程序的主要逻辑。

如果我更改当前用户,我正在努力找出如何重新渲染我的库组件。自从这是我的第一个项目以来,我不想玩弄正确的身份验证或创建路由器。所以我只是制作了一个登录表单,每当用户输入他的名字并登录时,我都会将库应用程序渲染到 DOM 上。

Login = React.createClass({

  _handleSubmit: function () {

    var inp = this.refs.login.getDOMNode();

    sessionStorage.setItem("username", inp.value);
    console.info('User Credentials saved to SessionStorage');
    inp.value = '';

    React.renderComponent(
      <Library />,
      document.querySelector('#content')
    );
  },

  render: function () {
    return (
      <div className="panel panel-default">
        blabla
                  <button className="btn btn-default" type="button" onClick={this._handleSubmit} >
                    Login
                  </button>
        blabla
      </div>
    );
  }
});

这很好用,但我认为这远非最佳方法。每当我再次登录时,react 都会将 Library 组件中的新实例重新渲染到 DOM 节点中。我根本不处理解构,我认为这很糟糕:(我知道反应不会追加,而是擦除并填充到节点中,但事件处理程序可能会保留等。

那么对于我的情况,什么可能是一个好的解决方案?

我有 3 种可能的解决方案

  1. 如果我以不同的用户重新登录以重新呈现自身,我应该开发一个事件系统以便能够通知库组件,或者
  2. 我可以在 Login & Library 上建立父子关系,所以当我修改 Login 组件的状态时,我的 Library 应用程序也会重新渲染。
  3. 调用将更新组件的操作
  4. 坚持当前

:) 感谢您的任何回答,干杯

暗示:

应用程序.js

'use strict';
var React = require('react'),
    Login = require('./components/Login.jsx');

// Dev-tools
window.React = React;

React.renderComponent(
  Login(),
  document.querySelector('#login')
);

登录.jsx

提到鞋面

图书馆.jsx

/** @jsx React.DOM */
'use strict';
var React = require('react'),
    BookShelf = require('./BookShelf.jsx'),
    Store = require('../stores/Store'),
    Library;

/**
 * Gets state from Storage
 * @returns {{books: BookCollection, users: UserCollection, categories: CategoryCollection}}
 */
function getState() {
  var state = Store.getAll();
  return {
    books: state.books,
    users: state.users,
    categories: state.categories
  };
}

Library = React.createClass({
  getInitialState: function() {
    return getState();
  },
  componentDidMount: function() {
    Store.addChangeListener(this._onChange);
    Store.initialize();
  },
  componentWillUnmount: function() {
    Store.removeChangeListener(this._onChange);
  },
  _onChange: function() {
    this.setState(getState());
  },
  render: function() {
    return (
      <div>
        <BookShelf
          books={this.state.books}
          users={this.state.users}
          categories={this.state.categories}
        />
      </div>
    );
  }
});

module.exports = Library;
4

1 回答 1

5

如果这是一个 Flux 应用程序,那么您希望获取所有应用程序逻辑和应用程序状态并将其移动到一个商店(或多个商店)中。

现在,看起来你在与图书馆相关的事情上做得很好。我将重命名该商店 LibraryStore。但是您可能需要 AppStore 或 UserStore 或 SessionStore 或具有与登录状态、当前用户和身份验证令牌相关的逻辑和数据的东西。

因此,一旦用户登录,是的,您会想要创建一个操作(选项#3),让您应用程序中的所有不同商店都知道您的用户已登录,但主要是通知 AppStore。然后你的顶级控制器视图可以监听 AppStore 并决定显示什么。如果您使用 React 的事件模型,则无需担心清理事件处理程序。Flux 控制器视图不使用 React 模型,因此我们必须在卸载时清理它们。

您的部分困难可能来自模拟异步流程。例如,身份验证将需要服务器调用,并且您的新操作将在该调用的成功/错误回调中创建。要针对 localStorage 进行模拟,您可以对存储进行同步查询,然后调用两种不同的操作之一来判断成功/失败。

于 2014-10-25T23:39:12.197 回答