it-swarm.com.ru

Я не могу понять, почему компоненты с «connect ()» с учетом состояния в реакции

Мой вопрос такой же, как и заголовок.

Допустим, я написал следующий код.

class TODOList extends Component {  
  render() {
    const {todos, onClick} = this.props;
    return (
      <ul>
            {todos.map(todo =>
                <Todo 
                    key={todo.id}
                    onClick={onClick}
                    {...todo}
                />
             )}
      </ul>
    );
  }
}


const mapStateToProps = (state) => {  
  return {
    todos: state.todos
  }
}


const mapDispatchToProps = (dispatch) => {  
    return {
        onClick(data){
          dispatch(complete(data)) 
        }
    }
}


export default connect(mapStateToProps,mapDispatchToProps)(TODOList); 

Теперь, после последней строки, этот код будет экспортировать компонент TODOList с состоянием в качестве реквизита. Дело не в том, что оно содержит состояние, а только в полученном состоянии и будет иметь их как "реквизиты", как объясняет имя метода "mapStateToProps".

В промежуточном посте ( https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d ), написанном Даном Абрамовым, компонент контейнера обрабатывает данные как состояние, а свойство представления - как реквизит. Разве это не презентационный компонент, который работает с данными в качестве реквизита? Я застрял с мыслью, что правильный контейнер должен быть таким, как показано ниже.

class CommentList extends React.Component {
  this.state = { comments: [] };

  componentDidMount() {
    fetchSomeComments(comments =>
      this.setState({ comments: comments }));
  }
  render() {
    return (
      <ul>
        {this.state.comments.map(c => (
          <li>{c.body}—{c.author}</li>
        ))}
      </ul>
    );
  }
}

Я не уверен, почему response-redux назвал API 'mapStateToProps', когда я попытался сделать контейнерный компонент с состоянием (без обработки данных по свойству)

9
Rhee

Прежде всего, эти руководящие принципы не являются частью Библии
Вы должны написать код, который легко рассуждать для YOU и вашей КОМАНДЫ

Я думаю, что вы что-то упустили. Контейнер-редуктор отличается от Реактивного контейнера.
Я имею в виду, connect создаст для вас контейнер, это не означает, что упакованный компонент is контейнер. 

Как правило, вы можете экспортировать обе версии из одного и того же файла: Контейнер (подключенная версия) и презентационная версия (не связанная). 

Другая вещь, которая обычно сбивает людей с толку, это имя функции и аргумент mapStateToProps.
Я предпочитаю имя mapStoreToProps как в 

сопоставьте хранилище redux с реквизитами компонента. 

имя state может сбивать с толку, когда мы находимся в контексте react.

Правка
Как продолжение вашего комментария: 

Я совершенно не знал, что эти два на самом деле разные. Не могли бы вы рассказать мне о более подробной информации

Они отличаются тем, как connect создает для вас «Контейнер». 

connect является Компонентом высокого порядка, который создает Контейнерный компонент для нас со всеми функциями логики подписки + для передачи частей хранилища и создателей действий его дочерним элементам в качестве реквизитов (mapStateToProps & mapDispatchToProps).

«Нормальный» Контейнер обычно относится к компоненту, который вы пишете от руки, часто он не имеет отношения к тому, как все должно выглядеть, но вместо этого имеет дело с определенной логикой приложения.

Что касается других комментариев, таких как

HoC connect ofact-redux просто внедряет свойства, которые вы можете запросить, в ваш компонент. Он возвращает новый компонент, обернутый вокруг вашего компонента, так что он может обновлять ваш компонент всякий раз, когда изменяется состояние, в котором вы заинтересованы в хранилище с избыточностью.

Как я уже упоминал выше, это частично верно. Это не просто внедрение свойств в наш компонент, его подписка на хранилище, получение его из Provider (через context) и выполнение всего этого с учетом оптимизации, поэтому нам не придется делать это самостоятельно. 

Я не уверен, как mapStateToProps может кого-то запутать. Мы говорим о государственной библиотеке управления

Я видел некоторых разработчиков, которые неправильно поняли это, потому что react имеет state, а redux имеет store (по крайней мере, так его называли в большинстве учебных пособий и документации).
Это может сбить с толку некоторых людей, которые плохо знакомы с react или redux

Правка 2

Это немного сбивало с толку из-за предложения «это не означает, что упакованный компонент является контейнером». Почему упакованный компонент не является контейнером? Разве компонент, созданный методом connect, также не является контейнером?

Я имею в виду, что завернутый компонент, который вы написали не обязательно Контейнер.
Вы можете подключить компонент «Презентация»: 

const Link = ({ active, children, onClick }) => {
  if (active) {
    return <span>{children}</span>
  }

  return (
    <a
      href=""
      onClick={e => {
        e.preventDefault()
        onClick()
      }}
    >
      {children}
    </a>
  )
}

// ...
export default connect(mapState, mapDispatch)(Link)
10
Sagiv b.g

mapStateToProps будет вызываться при изменении данных хранилища. Он передаст возвращенный объект как новый реквизит для компонента. Это не повлияет на состояние компонента. Если вы хотите установить новое состояние после того, как компонент получил новые реквизиты, вам нужно использовать другой метод жизненного цикла: static getDerivedStateFromProps (в более ранних версиях реагировать componentWillRecieveProps). Объект, возвращаемый static getDerivedStateFromProps, будет вашим новым состоянием.

https://reactjs.org/docs/state-and-lifecycle.html#adding-lifecycle-methods-to-a-class

connect() подключит ваш компонент к магазину приставок. Без функции соединения (конечно) ваша mapStateToProps не будет работать.

Я не уверен, почему response-redux назвал API 'mapStateToProps'

Мы говорим о состоянии магазина :)

2
messerbill

Целью высокого уровня является бесшовная интеграция управления состоянием Redux в приложение React. Redux вращается вокруг магазина, где существует все государство. Нет никакого способа напрямую изменить хранилище, кроме как через редукторы, которые получают действия от создателей действия, и для этого нам нужно, чтобы действие было отправлено от создателя действия.

Функция connect() напрямую соединяет наши компоненты с хранилищем Redux, принимая состояние в хранилище Redux и отображая его в prop.

Это сила Redux и поэтому мы его используем.

Допустим, вы создаете компонент с именем LaundryList и хотите, чтобы он отображал список для стирки. После того, как вы связали Provider в своем «родительском» компоненте, я поместил его в кавычки, потому что технически Provider является компонентом, поэтому он становится родительским.

Затем вы можете импортировать функцию connect() из react-redux, передать ее mapStateToProps, чтобы получить этот список стирки из хранилища Redux в ваш компонент LaundryList.

Теперь, когда у вас есть список белья внутри компонента LaundryList, вы можете сосредоточиться на создании списка элементов из них следующим образом:

class LaundryList extends Component {
  render() {
    console.log(this.props.linens);
    return <div>LaundryList</div>;
  }
}

Он содержит список объектов белья, и для каждого списка белья внутри него мы собираемся вернуть некоторый jsx, который будет представлять это белье в моем списке.

Вернувшись в свой компонент списка белья, я добавлю вспомогательный метод в компонент списка белья, который называется списком рендеринга:

class LaundryList extends Component {
  renderList() {

  }

  render() {
    return <div>LaundryList</div>;
  }
}

Итак, эта цель этого вспомогательного метода состоит в том, чтобы взять список белья, отобразить их и вернуть большой шарик jsx, например, так:

class LaundryList extends Component {
  renderList() {
    return this.props.linens.map((linen) => {
       return (

       );
    });
  }

  render() {
    return <div>LaundryList</div>;
  }
}
0
Daniel