При доступе к реквизитам компонента «this» не определено после отображения состояния на реквизиты - PullRequest
0 голосов
/ 27 января 2019

При использовании response-redux и отображения состояния в реквизит с помощью connect () полученное состояние имеет правильные значения, но при доступе к переменным через this.props «this» всегда не определено.

При нажатии кнопки(там только для целей тестирования) на компоненте боковой панели второй журнал консоли всегда завершается ошибкой с помощью TypeError: Невозможно прочитать свойство 'props' undefined в console.log (this.props.visibility).

Я пропалчто-то дополнительное, что необходимо для того, чтобы разрешить доступ к новым сопоставленным значениям в mapStateToProps через this.props?или даже если я должен получить доступ к ним другим способом, кроме 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 голосов
/ 27 января 2019

Это относится к JavaScript#lexical scoping.

Необходимо привязать к компоненту this, используя .bind или JavaScript#arrow function.

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
}
0 голосов
/ 27 января 2019

Когда вы пишете функции внутри компонента class / statefull, им не нужно ключевое слово function перед именем функции.Таким образом, тестовая функция может быть написана как test () {или стрелка function test = () => {

Причина, по которой это не определено внутри функции в вашем случае, потому что функция нуждается в связывании для доступа к этому и состоянию или подпрограммам,Либо вам нужно вручную связать функцию в конструкторе, либо заменить ее на функцию стрелки, как я делал ниже

Подход 1:

Вручную связать функцию в конструкторе

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

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

ИЛИ

Approach2:

Вы можете изменить функцию теста на функцию стрелки, поэтому ручная привязка в конструкторе не требуется, поскольку функции стрелки принимают привязку автоматически, поэтому она доступна внутри функции стрелки

Изменить

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

на

test = () => {
  console.log("hello");
  console.log(this.props.visibility);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...