访问组件的道具时,将状态映射到道具后未定义“ this”

时间:2019-01-27 17:50:31

标签: javascript reactjs redux react-redux

虽然使用react-redux并通过connect()将状态映射到props,但是接收到的状态具有正确的值,但是通过this.props访问变量时,“ this”始终未定义。

按下侧边栏组件上的按钮(仅用于测试目的)时,第二个控制台日志始终会失败,并显示TypeError:无法读取console.log(this.props.visibility)上未定义的属性“ props”。

我是否缺少一些必要的附加信息,以允许通过this.props访问mapStateToProps中新映射的值?甚至我应该以this.props之外的其他方式访问它们。

谢谢。

组件

import React, { Component } from 'react';
import {connect} from 'react-redux';
import {toggleSidebarVisibility } from '../../actions/layoutActions';


class Sidebar extends Component{

    render(){
      return(
        <div>
          <button class='btn btn-secondary' onClick={test}>B</button>
        </div>      
      );        
    }
}

function test(){
  console.log("hello");
  console.log(this.props.visibility)

}

const mapStateToProps = (state) => {
  console.log(state);
  console.log(state.layout.sidebarVisibility);
  return {
    visibility: state.layout.sidebarVisibility,
  }
};

App.js

import React, { Component } from 'react';
import logo from './logo.svg';
import { Provider } from 'react-redux';
import Sidebar from './components/layout/Sidebar';
import Header from './components/layout/Header';
import store from './store';

class App extends Component {
  render() {
    return (
      <Provider store ={store}>
        <div className="App">
          <Header />
          <Sidebar/>
        </div>
      </Provider>
    );
  }
}

export default App;

Store.js

import { createStore, applyMiddleware,compose} from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';

const initialState = {

};

const middleWare = [thunk];

const store = createStore(rootReducer,initialState,compose(
    applyMiddleware(...middleWare),
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
    ));

export default store;

RootReducer

import {combineReducers } from 'redux';
import layoutReducer from './layoutReducer';

export default combineReducers({
    layout : layoutReducer
});

LayoutReduccer

import {TOGGLE_SIDEBAR_VIS} from '../actions/types';

const initialState  = {
    sidebarVisibility : true
}

export default function(state = initialState,action){
    switch(action.type){
        case TOGGLE_SIDEBAR_VIS:
            return{ ...state,sidebarVisibility:action.payload};   
        default:
            return state;
    }
}

2 个答案:

答案 0 :(得分:0)

当您在class / statefull组件内编写函数时,它们不需要在函数名之前输入function关键字。所以测试函数可以写成test(){或箭头函数test =()=> {

在您的情况下,这在函数内部未定义的原因是,函数需要绑定才能访问此函数以及状态或道具。您需要像在下面那样手动将函数绑定到构造函数中,或将其更改为箭头函数

方法1:

在构造函数中手动绑定函数

      constructor(props){
           super(props);
           this.test = this.test.bind(this);
       }

       test = () => {
          console.log("hello");
          console.log(this.props.visibility);
      }

OR

方法2:

您可以将测试功能更改为箭头功能,因此不需要在构造函数中进行手动绑定,因为箭头功能会自动进行绑定,因此可以在箭头功能中使用

更改

function test(){
  console.log("hello");
  console.log(this.props.visibility);
}

收件人

test = () => {
  console.log("hello");
  console.log(this.props.visibility);
}

答案 1 :(得分:0)

这与JavaScript#lexical scoping有关。

需要使用thisJavaScript#arrow function绑定到组件.bind

Sol1:使用JavaScript#arrow function

test = () => {
  console.log("hello");
  console.log(this.props.visibility)

}

Sol2::使用JavaScript#bind显式使用此绑定。

内部构造函数:

constructor(){

  this.test = this.test.bind(this);
}


test(){
  //code
}