如何从深层组件访问redux变量和函数

时间:2017-10-20 08:47:09

标签: javascript reactjs react-redux frontend

我对redux的实现感到有些困惑。

让我们说我的应用程序具有以下组件结构:

-App
--ProfilationStep
---ProfilationStep1
----React-Select (http://jedwatson.github.io/react-select/)

我需要使用redux,因为应用程序会变得越来越大,所以我开始为React-Select组件设置Actions,Reducers和Action类型。我还在App.js文件中设置了mapStateToProps。

现在我需要知道如何将存储在redux中的数据传递/访问到其他组件(例如React-Select)以及如何使用我声明的操作对其进行编辑。

这是我的 index.js 文件

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import  ProfilationSelectReducer  from './components/reducers/profilationSelect';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

const store = createStore(
    ProfilationSelectReducer
    );

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>, document.getElementById('root'));
registerServiceWorker();

这是我的 App.js

import React, { Component } from 'react';
import PropTypes from 'prop-types'
import { bindActionCreators} from 'redux'
import Profilation from './components/Profilation'
import ProfilationStep from './components/Profilation/ProfilationStep'

import { connect } from 'react-redux';
import * as SelectActionCreators from './components/actions/profilationSelect'
import 'react-select/dist/react-select.css';

class App extends Component {
  static propTypes = {
    steps: PropTypes.array.isRequired
  };

  render() {

    console.log(this.props)
    const { dispatch, steps } = this.props;
    const changeValue= bindActionCreators(SelectActionCreators.changeValue, dispatch);

   const stepComponents = this.props.steps.map((step, index) => (
      <ProfilationStep
        key={index}
        index={index}
        step={step}
      />
    ));

   return (
      <div className="repower-app">

       { stepComponents }
      </div>
    );
  }
} 

const mapStateToProps = state => ({
  steps:state.steps
});

export default connect(mapStateToProps)(App);

这是我的 ProfilationStep.js 文件

import React, { Component } from 'react';
import PropTypes from 'prop-types'
import ProfilationStep1 from './ProfilationStep1'
import ProfilationStep2 from './ProfilationStep2'
import ProfilationStep3 from './ProfilationStep3'
import ProfilationStep4 from './ProfilationStep4'
import ProfilationStep5 from './ProfilationStep5'


const ProfilationStep = props =>

<div className='ProfilationStep'>
    {props.index===0 &&
        <ProfilationStep1 
            step={props.step}
        />
    }
    {props.stepIndex===2 &&
        <ProfilationStep2
        handleSelect={props.handleSelect} 
        handleInput={props.handleInput} 
        expend={props.expend}
        period={props.period}
        light={props.light}
        gas={props.gas}
        />
    }
    {props.stepIndex===3 &&
        <ProfilationStep3
        handleSelect={props.handleSelect} 
        environment={props.environment} 
        />
    }

    {props.stepIndex===4 &&
        <ProfilationStep4 
            flexibility={props.flexibility}
            handleSelect={props.handleSelect} 
        />
    }
    {props.stepIndex===5 &&
        <ProfilationStep5 
            customize={props.customize}
            handleSelect={props.handleSelect} 
        />
    }

</div>

export default ProfilationStep

这是我的 ProfilationStep1.js 文件

import React, { Component } from 'react';
import Select from 'react-select';
import PropTypes from 'prop-types'

var jobOptions = [
  { value: 'edilizia', label: 'Edilizia' },
  { value: 'editoria', label: 'Editoria' },
  { value: 'educazione', label: 'Educazione' }
];



const ProfilationStep1 = props => 

<div className='ProfilationStep'>
    La mia attivit&agrave; si occupa di <Select
                  name="job"
                  value={props.step.job}
                  onChange={e => props.changeValue(e.target.value)}
                  options={jobOptions}
                  />    

</div>

ProfilationStep1.propTypes = {

    //isComplete: PropTypes.bool.isRequired,
    //isActive: PropTypes.bool.isRequired
    job: PropTypes.string.isRequired,
    service: PropTypes.string.isRequired,
    handleSelect: PropTypes.func.isRequired
}

export default ProfilationStep1

这是我的 reducer

import * as ProfilationSelectActionTypes from '../actiontypes/profilationSelect';

const initialState = {


    steps: [{
        job: "",
        service: ""
    }],
}

export default function ProfilationSelectReducer (state=initialState, action){
    switch(action.type){
        case ProfilationSelectActionTypes.CHANGE_VALUE:
        return {
            ...state,
            steps:[{
                job: action.value
            }]

        };
        default:
        return state;
    }
}

这是我的 actiontypes 文件

export const CHANGE_VALUE ='profilationSelect/CHANGE_VALUE';

最后,这是我的操作文件

import * as ProfilationSelectActionTypes from '../actiontypes/profilationSelect';

export const changeValue = value =>{
    return{
        type: ProfilationSelectActionTypes.CHANGE_VALUE,
        value
    }
}

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

你肯定是正确的。

解决方案很简单:将状态绑定到反应道具。使用道具,你可以做任何你喜欢的事情(例如,将它们传递给react-select)。如果要修改它,则必须映射&#34; mapDispatchToProps&#34;,将执行操作的函数映射到props。这与&#34; mapStateTopProps&#34;:

的作用相同

App.js结束(将您的操作文件导入到顶部,命名为&#34; profilationSelectActions&#34;此处):

const mapStateToProps = state => ({
  steps:state.steps
});

const mapDispatchToProps = dispatch => ({
  updateJobValue: (value) => dispatch(profilationSelectActions.changeValue(value))
}

// Also add here mapDispatchToProps
export default connect(mapStateToProps, mapDispatchToProps)(App);

现在功能&#34; updateJobValue&#34;可以在app.js的道具中找到您现在可以轻松地将其传递给组件和react-select的onChange事件:

在ProfilationStep1.js中更改此行:

onChange={e => props.changeValue(e.target.value)}

到此(在你传递函数updateJobValue之后)

onChange{e => props.updateJobType(e.target.value)}

之后,updateJobType应该一直到App.js,然后发送动作。之后,应用程序将使用新步骤重新呈现。