Задать вопрос
@s24344

Как правильно передать props в React?

Всем привет. Разбираюсь с небольшой задачкой на React.js. В компоненте TimerComponent у меня есть метод handleStart. В нем уже описан механизи изменения state в функции setTimeout.
Но у меня:
this.props {
   currentInterval: undefined
}

Я не силен в React, подскажите, где потерялся этот props?
import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';


const createStore = (reducer, initialState) => {
    let currentState = initialState;
    const listeners = [];

    const getState = () => currentState;

    const dispatch = action => {
        currentState = reducer(currentState, action);
        listeners.forEach(listener => listener())
    }

    const subscribe = listener => listeners.push(listener);

    return {getState, dispatch, subscribe}
}

const connect = (mapStateToProps, mapDispatchToProps) =>
    Component => {
        class WrappedComponent extends React.Component {
            render() {
                return (
                    <Component
                        {...this.props}
                        {...mapStateToProps(this.context.store.getState(), this.props)}
                        {...mapDispatchToProps(this.context.store.dispatch, this.props)}
                    />
                )
            }

            componentDidUpdate() {
                console.log('componentDidUpdate');
                this.context.store.subscribe(this.handleChange)
            }

            handleChange = () => {
                console.log('handleChange');
                this.forceUpdate()
            }
        }

        WrappedComponent.contextTypes = {
            store: PropTypes.object,
        }

        return WrappedComponent
    }

class Provider extends React.Component {
    getChildContext() {
        return {
            store: this.props.store,
        }
    }

    render() {
        return React.Children.only(this.props.children)
    }
}

Provider.childContextTypes = {
    store: PropTypes.object,
}

// APP

// actions
const CHANGE_INTERVAL = 'CHANGE_INTERVAL'

// action creators
const changeInterval = value => ({
    type: CHANGE_INTERVAL,
    payload: value,
})

// reducers
const reducer = (state, action) => {
    switch (action.type) {
        case CHANGE_INTERVAL:
            return state += action.payload

        default:
            return {}
    }
}

// components

class IntervalComponent extends React.Component {
    render() {

        console.log('class IntervalComponent this.state', this.state);
        console.log('class IntervalComponent this.props', this.props);

        return (
            <div>
                <span>Интервал обновления секундомера: {this.props.currentInterval} сек.</span>
                <span>
                  <button onClick={() => this.props.changeInterval(-1)}>-</button>
                  <button onClick={() => this.props.changeInterval(1)}>+</button>
                </span>
            </div>
        )
    }
}

const Interval = connect(dispatch => ({
        changeInterval: value => dispatch(changeInterval(value)),
    }),
    state => ({
        currentInterval: state,
    }))(IntervalComponent)

class TimerComponent extends React.Component {
    state = {
        currentTime: 0
    }

    handleStart = () => {

        console.log('this.state', this.state);
        console.log('this.props', this.props);

        setTimeout(() => this.setState({
            currentTime: this.state.currentTime + this.props.currentInterval,
        }), this.props.currentInterval)
    }

    handleStop = () => {
        console.log(this);
        this.setState({currentTime: 0})
    }

    render() {

        console.log('this.props', this.props);

        return (
            <div>
                <Interval/>
                <div>
                    Секундомер: {this.state.currentTime} сек.
                </div>
                <div>
                    <button onClick={this.handleStart}>Старт</button>
                    <button onClick={this.handleStop}>Стоп</button>
                </div>
            </div>
        )
    }
}

const Timer = connect(state => ({
    currentInterval: state,
}), () => {
})(TimerComponent)

// init
ReactDOM.render(
    <Provider store={createStore(reducer)}>
        <Timer />
    </Provider>,
    document.getElementById('app')
)
  • Вопрос задан
  • 969 просмотров
Подписаться 1 Простой Комментировать
Помогут разобраться в теме Все курсы
  • Яндекс Практикум
    Мидл фронтенд-разработчик
    5 месяцев
    Далее
  • Яндекс Практикум
    React-разработчик
    3 месяца
    Далее
  • Яндекс Практикум
    Фронтенд-разработчик
    10 месяцев
    Далее
Пригласить эксперта
Ответы на вопрос 1
rockon404
@rockon404 Куратор тега React
Frontend Developer

...Разбираюсь с небольшой задачкой на React.js.
...Я не силен в React.

По-хорошему так не делается.

Я не знаю чей код вы использовали, но для использования контекста уже давно не надо использовать PropTypes.
Не передаете initialState.
В вызове connect вы местами передаете сначала mapDispatchToProps, затем mapStateToProps.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
ITK academy Нижний Новгород
от 50 000 до 90 000 ₽
ITK academy Воронеж
от 50 000 до 90 000 ₽
IT ATLAS Москва
от 200 000 до 250 000 ₽