2016-10-20 6 views
0

У меня есть компонент контейнера, который соединяется с состоянием, которое я сделал с immutable.js. Когда я обновляю состояние, мой инспектор redux сообщает мне, что состояние обновлено, но мой компонент не получает новые обновления и не реинжинирует.Мой компонент не обновляется, я мутирую состояние?

Мой компонент контейнера:

import React, { Component } from 'react' 
import { connect } from 'react-redux' 
import { setCategoryActive } from '../actions' 
import Category from '../components/Category' 

class MenuList extends Component { 


    constructor(props) { 
    super(props) 
    this.categories = this.props.categories 
    this.subreddits = this.props.subreddits 
    this.allCategories = this.categories.get("allCategories") 
    this.byName = this.categories.get("byName") 
    } 

    printSubreddits(category) { 
    const subreddits = this.byName.get(category) 
    const subredditsByName = subreddits.get("subredditsByName") 

    const list = subredditsByName.map((subreddit, i) => { 
     return <p className="swag" key={i}>{subreddit}</p> 
    }) 

    return list 
    } 

    isCategoryActive(category) { 
    const cat = this.byName.get(category) 
    return cat.get("active") 
    } 

    printCategory(category, i) { 
    console.log(this.isCategoryActive(category)) 
    return (
     <div className="category-container" key={i}> 
     <Category name={category} 
      active={this.isCategoryActive(category)} 
      setActive={this.props.setCategoryActive.bind(this, category)} /> 
     {this.isCategoryActive(category) ? this.printSubreddits(category) : null} 
     </div> 
    ) 
    } 


    render() { 

    return (
     <div> 
     {this.allCategories.map((category, i) => { 
      const x = this.printCategory(category, i) 
      return x 
     }, this)} 
     </div> 
    ) 
    } 
} 

const mapStateToProps = (state) => ({ 
    categories: state.subredditSelector.get('categories'), 
    subreddits: state.subredditSelector.get('subreddits') 
}) 

export default connect(mapStateToProps, { 
    setCategoryActive 
})(MenuList); 

Моя категория компонент

class Category extends Component { 

    printToggle(active) { 
    if (active) { 
     return <span> [-]</span> 
    } else { 
     return <span> [+]</span> 
    } 
    } 

    componentWillReceiveProps(nextProps) { 
    this.printToggle(nextProps.active) 
    } 

    render() { 

    const { setActive, active, name } = this.props 

    return (
     <div className="category-container"> 
     <a onClick={setActive} 
     href="#" 
     className="category-title"> 
      {name} 
      {this.printToggle(active)} 
     </a> 
     </div> 
    ) 
    } 

} 

export default Category 

И мой редуктор

import { fromJS } from 'immutable' 
import { 
    SET_SUBREDDIT_ACTIVE, 
    SET_CATEGORY_ACTIVE 
} from '../actions' 
import List from '../data/nsfw_subreddits.js' 

const initState = fromJS(List) 

const subredditSelector = (state = initState, action) => { 
    switch (action.type) { 
    case SET_SUBREDDIT_ACTIVE: 
     return state 
    case SET_CATEGORY_ACTIVE: 
     return state.updateIn(['categories', 'byName', action.payload.name], 
     x => x.set('active', !x.get('active'))) 
    default: 
     return state 
    } 
} 

export default subredditSelector 

Кусок моего состояния, я закодированы как объект JSON

const list = { 
    categories: { 
    byName: { 
     "example": { 
     name: "example", 
     id: 1, 
     active: true, 
     subredditsByName: ["example", "example"] 
     }, 
     "example": { 
     name: "example", 
     id: 2, 
     active: true, 
     subredditsByName: ["example"] 
     }, 
     "example": { 
     name: "example", 
     id: 3, 
     active: true, 
     subredditsByName: ["example", "example", "example"] 
     } 
    }, 
    allCategories: ["example", "example", "example"] 
    }, 
    subreddits: { 

Я предполагаю, что мой редуктор мутирует состояние? Хотя я не уверен, как, поскольку я использую неизменяемые функции js?

+0

Привет, Альберт, я просто хочу кое-что проверить здесь. Вы ожидаете, что «Мой контейнерный компонент» повторно отобразит AllCategories как ваши изменения состояния? Если это так, я думаю, проблема здесь в том, что this.allCategories устанавливается только один раз в вашем конструкторе, и ссылка никогда не изменяется. Я предлагаю добавить allCategories к вашему методу mapStateToProps. Я не могу проверить это сам прямо сейчас, поэтому я могу быть в стороне, но я думаю, что этот подход стоит попробовать! – Spen

ответ

1

Поэтому я исправил эту проблему, изменив конструктор от конструктора к регулярной функции и назвал его в верхней части моего метода визуализации!

+0

Лучшим местом для обновления вашего компонента на основе изменений prop является компонентWillReceiveProps. Помещение этого материала в рендеринг означает, что он получает вызов чаще, чем необходимо, что может не иметь значения для вашего компонента. – luqmaan

0

Вы все равно должны держать свой конструктор, но только в нем то, что должно быть сделано, когда объект сначала создается:

constructor(props) { super(props) }

И да, имея

cleanPropData(){ this.categories = this.props.categories this.subreddits = this.props.subreddits this.allCategories = this.categories.get("allCategories") this.byName = this.categories.get("byName") }

Это хорошо. Я не слышал, чтобы кто-то вызывал его в верхней части функции рендеринга. Приятно знать, что работает.