简体   繁体   中英

How not to pass down props using Redux?

I just learned that we can reduce the complexity of a react project using redux. With the single source of truth (store), we don't need to pass down states to components that don't need them. I'm struggling with understanding this statement.

Say I have three components, A, B and C. A is a container with a state called text . B is a custom button and C only displays the text. Whenever B is clicked, it updates the state in A. Then C will display the updated text.

  A
 / \
C   B

I have tried to apply redux to the app and found that I still need to pass down the props. The only difference is that I am passing down this.props.text instead of this.state.text .

I can't see how redux can benefit an app like this.

App.js

import React, { Component } from "react";
import { connect } from 'react-redux'; 

import MyButton from "./MyButton";
import { handleClick } from "./actions"; 
import Display from "./Display"

class App extends Component {
  render() {
    return (
      <div className="App">
        <MyButton onClick={()=>this.props.handleClick(this.props.text)} />
        <Display text={this.props.text} />
      </div>
    );
  }
}

const mapStateToProps = state => ({
    text: state.text.text
})

const mapDispatchToProps = dispatch => ({
  handleClick: (text) => dispatch(handleClick(text))
})

export default connect(mapStateToProps, mapDispatchToProps)(App)

Also, if we have another app with structure shown below. Say B doesn't care about A's state but C needs it to display the text. Can we skip B and just let C use A's state?

A
|
B
|
C

I think I found the solution. I simply created a file stores.js and export the store. So I can import it and retrieve the state by invoking store.getState() whenever a child component needs the it.

You shouldn't do that.

Instead you should use the connect function with each component, everywhere in the structure, that needs access to a property of your store.

But, if you only have three components, you probably don't need Redux or a global store for your app state.

Redux comes with a lot of opinions on how to handle your global state that are meant to secure your data flow.

Otherwise, if you only need to avoid prop drilling (ie passing down props through many levels, as in your second exemple) you may use the native React context API that does just that: reactjs.org/docs/context.html

Edit Things should be clearer with an exemple:

import React, { Component } from "react";
import { connect } from 'react-redux'; 

import MyButtonCmp from "./MyButton";
import DisplayCmp from "./Display"

import { handleClick } from "./actions"; 

// I am doing the connect calls here, but tehy should be done in each component file
const mapStateToProps = state => ({
    text: state.text.text
})
const Display = connect(mapStateToProps)(DisplayCmp)

const mapDispatchToProps = dispatch => ({
  onClick: (text) => dispatch(handleClick(text))
})
const MyButton =  connect(null, mapDispatchToProps)(MyButtonCmp)

class App extends Component {
  render() {
    return (
      <div className="App">
        {/* No need to pass props here anymore */}
        <MyButton />
        <Display />
      </div>
    );
  }
}

// No need to connect App anymore
// export default connect(mapStateToProps, mapDispatchToProps)(App)

export default App

In this example, you may map app state to props using redux.

I don't see why you would process the information this way(with redux) unless you were planning on using the data in multiple parts of the application and wanted to re-use the action code.

See more: https://react-redux.js.org/using-react-redux/connect-mapstate

2nd question

Also, if we have another app with structure shown below. Say B doesn't care about A's state but C needs it to display the text. Can we skip B and just let C use A's state?

In Redux, yes.

With React Hooks, yes.

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