React/Redux. Access state from other component

2019-06-08 20:56发布

问题:

Im trying to access a components state from another component with not much of a success. So far my code looks like this:

The two components are rendered in App.js, the entry file. First components is a mobile navigation. That one should be open/closed depending on the state in component 2 wich is a toggle-button. Can anyone help me out?

Component 1.(In here i want to access the state of 'toggled' from component 2)

import * as style from './MobileNavigation.style'
import React, { Component } from 'react'
import Button from '../../components/Button'

class MobileNavigation extends Component {
render() {
return (
  <style.Background>
    <style.Menu>
      <style.MenuItem>
        <style.RouterLink to="home">home</style.RouterLink>
      </style.MenuItem>
      <style.MenuItem>
        <style.RouterLink to="about">about</style.RouterLink>
      </style.MenuItem>
      <style.MenuItem>
        <style.RouterLink to="contact">contact</style.RouterLink>
      </style.MenuItem>
    </style.Menu>
  </style.Background>
)
  }
}

export default MobileNavigation

Component 2

import React, { Component } from 'react'
import styled from 'styled-components'
import * as style from './Hamburger.style'

interface Props {
  width: string
  height: string
  fill: string
  toggled?: boolean
}

interface State {
  toggled?: boolean
}

const Svg = styled.svg`
  width: ${(props: Props) => props.width};
  height: ${(props: Props) => props.height};
`

class Hamburger extends Component<Props, State> {
  static defaultProps = {
    width: '100%',
    height: '100%',
    fill: '#172b41',
    toggled: true
  }

  constructor(props: any) {
    super(props)
    this.state = {
      toggled: true
    }
  }

  onClick(toggled: boolean) {
    this.setState({
      toggled: !this.state.toggled,
    })
  }

  render() {
    return (
      <style.Wrapper onClick={this.onClick.bind(this, this.props.toggled)}>
    {this.state.toggled ? (
      <div>closed</div>
    ) : (
      <div>open</div>
    )}
  </style.Wrapper>
)
}
}

export default Hamburger

回答1:

React Way:

if you want to do this in react it self (without redux) you need to create a state of shouldToggled and a function to control it in your parent component (App.js). then you need to pass the function to your hamburger component and pass the state in to other one and in your hamburger component you need to use function to change the state in your App.js component and by that your parent state would be updated an would cause a Rerender. this is called lifting state up technique and you can see it in react docs for more info.

Redux way:

redux way is a little bit complex tough. by that , you have two choices based on complexity of your component's parent/child relationship and how many levels your child is deep (which in your case is just one level deep), same as react way you need to have an state on redux store to control the toggled state of your components and you need to have an action creator too , in order to trigger that state change. then in your hamburger component you need to call that action creator to send the action to reducer in order to change the store, once the store is changed in an immutable way, the whole redux store would updated and immediately provided to your whole application, and finally would cause a rerender of your component.

finally:

make sure to use redux way only in complex situation b/c you would find it helpfull in those kind of situation rather that in simple cases like your current problem. and my advice for you could be: stick to the react lifting state up technique for your current problem, b/c it needs so much less boiler plate code in your case.