简体   繁体   中英

How do I use redux when a prop function is changing the state?

I'm trying to wrap my head around how one uses redux in the case where a prop that is being passed into a component is supposed to be used to change the state of the application.

I have a working example here .

let Input = ({handleChange}) => (
  <input type="text" onChange={handleChange('mySpecialInput')} />
)

let Text = ({message, color}) => (
  <span style={{color}}>{message}</span>
)

let App = ({message, color, handleChange}) => (
  <div>
    <Text message={message} color={color} /> <br />
    <Input handleChange={handleChange} />
  </div>
)

class ConnectedApp extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      color: 'orange',
      message: 'Hello World'
    }
    this.handleChange = this.handleChange.bind(this)
  }
  handleChange(id) {
    return (event) => {
      console.log(id)
      if (id === 'mySpecialInput') {
        this.setState({'color': event.target.value})
      }
    }
  }
  render() {
    return (
      <App 
        message={this.state.message} 
        color={this.state.color} 
        handleChange={this.handleChange} />
    )
  }
}

ReactDOM.render(
  <ConnectedApp/>,
  document.getElementById('react_example')
);

How would something simple like this be worked into using redux?

Here's the code above built using redux!

Working Example

let {createStore} = Redux
let {connect, Provider} = ReactRedux

// React component
let Input = ({handleChange}) => (
  <input type="text" onChange={handleChange('mySpecialInput')} />
)

let Text = ({message, color}) => (
  <span style={{color}}>{message}</span>
)

let App = ({message, color, handleChange}) => (
  <div>
    <Text message={message} color={color} /> <br />
    <Input handleChange={handleChange} />
  </div>
)

// Action

const CHANGE_COLOR = 'CHANGE_COLOR'

function changeColorAction(color) {
  return {
    type: CHANGE_COLOR,
    color
  }
}

// Reducer
function reducer(state = {color: "#ffa500"}, action) {
  let count = state.count
  switch (action.type) {
    case CHANGE_COLOR:
      return { color: action.color }
    default:
      return state
  }
}

// Store
let store = createStore(reducer)

// Map Redux state to component props
function mapStateToProps(state) {
  return {
    color: state.color,
    message: "Hello World"
  }
}

function changeColorDispatcher (dispatch) {
  return (id) => {
    return (event) => {
      if (id === 'mySpecialInput') {
        return dispatch(changeColorAction(event.target.value))
      }
    }
  }
}

// Map Redux actions to component props
function mapDispatchToProps(dispatch) {
  return {
    handleChange: changeColorDispatcher(dispatch)
  }
}

// Connected Component
let ConnectedApp = connect(
  mapStateToProps,
  mapDispatchToProps
)(App)

ReactDOM.render(
  <Provider store={store}>
    <ConnectedApp/>
  </Provider>,
  document.getElementById('react_example')
);

You can simply connect each of your components individually instead of using connect() on your top-level component and passing down the props in the hierarchy tree.

This will come way more handy.
See a working example!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM