Как компонент должен получить доступ к данным из хранилища?

В моем приложении React, когда пользователь входит в систему, его пользовательские данные устанавливаются на UserStore.currentUser. Как компоненты должны получить доступ к UserStore.currentUser?

Кажется, у компонента есть 4 варианта доступа к этим данным. Какой (если есть) правильный?

Вариант 1. Установите его в "состояние" компонента

  var ProfilePicture = React.createClass({
    getInitialState: function(){
      return {
        currentUser: UserStore.currentUser
      }
    },
    render: function(){
      return <h1>Hi my name is {this.currentUser.name}</h1>;
    }
  });

Вариант 2. Прямой доступ к ресурсу магазина

var ProfilePicture = React.createClass({
  render: function(){
    return <h1>Hi my name is {UserStore.currentUser.name}</h1>;
  }
});

Вариант 3. Доступ к свойству магазина с помощью метода получения

var ProfilePicture = React.createClass({
  render: function(){
    return <h1>Hi my name is {UserStore.getCurrentUser().name}</h1>;
  }
});

Вариант 4. Установите currentUser в состояние корневого компонента. Передать в качестве опоры всем остальным

var App = React.createClass({
  getInitialState: function(){
    return { currentUser: UserStore.currentUser };
  },
  render: function(){
    return <div>
      <ThingA />
      <ThingB />
      <ProfilePicture userName={this.state.currentUser.name} />
    </div>;
  }
});

var ProfilePicture = React.createClass({
  render: function(){
    return <h1>Hi my name is {this.props.userName}</h1>;
  }
});

person Don P    schedule 30.11.2015    source источник


Ответы (3)


Я не думаю, что это особенно хорошая идея в данном случае. Что, если name изменится? Было бы лучше connect хранить в представлении (контейнер компонента) и передавать name в ProfilePicture через реквизит. Это держит ваш компонент развязанным. Это также облегчает тестирование.

С точки зрения React 0.14 я бы написал что-то вроде этого:

export default ({name}) => <h1>{`Hi my name is ${name}`}</h1>

Определение компонентов на основе функций работает только в простых случаях.

person Juho Vepsäläinen    schedule 30.11.2015
comment
Это похоже на вариант 3, который я здесь написал? В основном я устанавливаю состояние корневого компонента приложения, а затем передаю его в качестве реквизита дочерним компонентам, которым это нужно. - person Don P; 30.11.2015

Ваш магазин содержит метод, который может вернуть вам данные, например

getUserinfo:function()
{
  return currentUser;
}

теперь вы можете получить доступ к любому из ваших компонентов, вам нужно просто вызвать магазин, например

var UserStore=require('./UserStore);

var currentuser=UserStore.getUserinfo();
person Dhaval Patel    schedule 30.11.2015
comment
Разве это не плохая идея, поскольку изменения в currentUser не приведут к повторному рендерингу компонента? - person Don P; 30.11.2015
comment
здесь нет возможности повторного рендеринга, потому что просто сохраните текущего пользователя в переменной и вернитесь туда, где это требуется - person Dhaval Patel; 30.11.2015
comment
@DonnyP, как только пользователь изменит ваш поток, будет вызван весь поток, и это изменение автоматически обновит текущую пользовательскую переменную, поэтому изменения будут применены - person Dhaval Patel; 30.11.2015

mixins: [
    Reflux.listenTo(UserStore,'onSessionChange'),
    ],
getInitialState() {
    return {
        name: '',
        other: ''
    };
},
componentDidMount() {
    UserActions.getUserInfo();
},
onSessionChange(userInfo) {
    this.setState({
        name: userInfo.name,
        other: userInfo.other
    })
},

Поскольку вы используете refluxjs, я думаю, что лучше слушать изменение данных в компоненте.

person Zhang Chao    schedule 13.12.2015