Answer the question
In order to leave comments, you need to log in
How to properly pass props to React?
Hello. I deal with a small problem on React.js. In the TimerComponent I have a handleStart method. It already describes the mechanics of changing the state in the setTimeout function.
But I:
this.props {
currentInterval: undefined
}
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')
)
Answer the question
In order to leave comments, you need to log in
...Understood with a small problem on React.js.
...I'm not strong in React.
Well, that's not how it's done.
I don't know whose code you used, but to use the context, you no longer need to use PropTypes.
Don't pass initialState.
In the connect call, you pass mapDispatchToProps first, then mapStateToProps in places.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question