Получить значение из Redux Store

145
19 октября 2021, 13:50

Есть movie reducer

const initialState = {
    movies: [],
    movie: {}
};
const moviesReducer = (state = initialState, action) => {
    switch (action.type) {
        case FETCH_MOVIES:
            return Object.assign({}, state, {
                movies: action.movies
            });
        case FETCH_MOVIE:
            return Object.assign({}, state, {
                movie: state.movies[action.index]
            });
        default:
            return state;
    }
};

Есть компонент Movies.jsx

class Movies extends Component {
    componentDidMount() {
        this.props.fetchMovies(movies) // (1);
        console.log(movies);
    }
    render() {
        return (
            <div className="movies">
                <div className="list">
                    ...
                </div>
                {this.props.children}
            </div>
        );
    }
}
function mapDispatchToProps(dispatch) {
    return bindActionCreators(
        {
            fetchMovies: fetchMoviesActionCreator,
            fetchMovie: fetchMovieActionCreator
        },
        dispatch
    );
}
export default connect(
    state => state,
    mapDispatchToProps
)(Movies);

Этот компонент помещает массив фильмов в хранилище см. (1) и выводит дочерний компонент Movie.jsx

class Movie extends React.Component {
    componentWillMount() {
        this.props.fetchMovie([someIndexHere]); // (2)
    }
    render() {
        return <div>Movie component</div>;
    }
}
export default connect(
    state => ({
        movie: state.movies.movie
    }),
    {
        fetchMovie: fetchMovieActionCreator
    }
)(Movie);

Почему-то когда я вызываю в компоненте Movies this.props.fetchMovie() см. (2), действие FETCH_MOVIE в moviesReducer выполняется, НО в конечном этоге в movie я получаю undefined

При таком обработчике действия

case FETCH_MOVIE:
     return Object.assign({}, state, {
         movie: state.movies.length
     });

Я получаю вот такое значение хранилища

Хотя в компоненте-родителе я устанавливаю state.movies массивом

Если же в компоненте Movies вызвать эти два метода подряд, то все работает как положено

class Movies extends Component {
    componentDidMount() {
        this.props.fetchMovies(movies);
        this.props.fetchMovie(2);
    }
    ...

Исходя из философии Redux насколько я понял, я могу абсолютно из любого компонента получить к данным хранилища, подключив компонент к нему функцией connect. Но по какой-то причине в дочернем компоненте, я получаю новую версию хранилища, которое уже не заполнено фильмами. В чем причина?

Answer 1

В компоненте Movies нужно было загружать данные не в componentDidMount, а в componentWillMount, т.к данные не успевали записываться в store до рендера дочернего компонента Movie

class Movies extends Component {
    - componentDidMount() {
    + componentWillMount() {
        this.props.fetchMovies(movies) // (1);
        console.log(movies);
    }
READ ALSO
Помогите решить две задачи на JS [закрыт]

Помогите решить две задачи на JS [закрыт]

Хотите улучшить этот вопрос? Обновите вопрос так, чтобы он вписывался в тематику Stack Overflow на русском

179
Стоит ли делать единую функцию обработки ajax запросов?

Стоит ли делать единую функцию обработки ajax запросов?

У меня есть длинный основной файл JS и все множество блоков кода где данные подгружаются через AJAx

106
Как передать в конвертор значение переменной?

Как передать в конвертор значение переменной?

У меня в таблице (WPF DataGrid) строки в зависимости от ряда условий должны иметь свойство IsEnabled True или FalseДля анализа условий написал простенький...

257