Вопрос по javascript, reactjs, redux, ecmascript-6 – Установить реквизиты по умолчанию для реагирующего компонента

3

Я хочу, чтобы у моего компонента приложения был реквизит по умолчанию, и я использую этот реквизит вmapStateToProps.

контейнеры / App.js
import React, { Component, PropTypes } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import Footer from '../components/Footer';
import TreeNode from '../containers/TreeNode';
import Home from '../containers/Home';
import * as NodeActions from '../actions/NodeActions'

export default class App extends Component {

  constructor(props, context), {
    super(props, context)
    this.props = {
      info:{
        path:'/'
      }
    }
  }

  componentWillMount() {
    // this will update the nodes on state
    this.props.actions.openNode('/');
  }

  render() {
    const { node , actions} = this.props
    console.log(this.props)

    return (
      <div className="main-app-container">
        <Home />
        <div className="main-app-nav">Simple Redux Boilerplate</div>
        {node.childNodes &&
          <div>{node.childNodes.map(node => <TreeNode key={info.path} info={node} tree={tree} actions={actions} />)}</div>
        }
        {!node.childNodes &&
          <div>no children</div>
        }
        {/*<Footer />*/}
      </div>
    );
  }
}

App.defaultProps = {
    info:{
      path:'/'
    }
};

function mapStateToProps(state, ownProps) {
  console.log('state')
  console.log(state)
  console.log('ownProps')
  console.log(ownProps)
  return {
    node: ownProps.info.path? state.TreeNodeReducer.tree[ownProps.info.path] : {}
  };
}


function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(NodeActions, dispatch)
  };
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(App);
редукторы / TreeNodeReducer.js
import { OPEN_NODE, CLOSE_NODE, GET_NODES } from '../constants/NodeActionTypes';
import UUID from "node-uuid"

const initialState = {
  open: false,
  info: {} 
}

class NodeModel {
    constructor(path, type, right) {
        this.name = path;
        this.path = path;
        this.type = type;
        this.right = right;
    }
}

let lastId = 0;

function getFileList() {
  var testNodes = []
  for (var i=0; i< 3; i++) {
    testNodes.push(new NodeModel(lastId,'d', i.toString()))
    lastId++;
  }

  return testNodes
}


const getNodes = (state, action) => {
  var { path } = action
  var tree = state.tree ? state.tree : {}
  tree[path] = getFileList(path)
  return {
    ...state,
    tree:tree
  };
};

export default function (state = initialState, action) {
  switch (action.type) {
    case OPEN_NODE:
      return { ...getNodes(state, action), open:true };
    case GET_NODES:
      return getNodes(state, action);
    case CLOSE_NODE:
      return {
        ...state,
        open:false
      };
    default:
      return state;
  }
}

Я пытался :

1: конструктор
  constructor(props, context) {
    super(props, context)
    this.props = {
      info:{
        path:'/'
      }
    }
  }
2: defaultProps:
App.defaultProps = {
    info:{
      path:'/'
    }
};

но ни одна из них не работает ... журнал всегда есть:

state имеет правильное значение по умолчанию, ноownProps пустой...

PS: Проект естьВот.

Ваш Ответ

2   ответа
4
1) два «экспорта по умолчанию»

export default вApp.js.

Попробуйте изменить:

export default class App extends Component

в

const App = class App extends Component.

А потом:

...

App.defaultProps = {
    info:{
      path:'/'
    }
};
...
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(App);
2) «defaultProps» и «ownProps»:

КакmapStateToProps вызывается до создания компонента (когда определены defaultProps),ownProps пустой. Вы можете попробовать два варианта:

1) это обходной путь:

App.defaultProps = {
  info: {
    path:'/' 
  }  
}

function mapStateToProps(state, ownProps) {
  console.log('state')
  console.log(state)
  console.log('ownProps')
  console.log(ownProps)

  const path = ownProps.info && ownProps.info.path ? ownProps.info.path : App.defaultProps.info.path;

  return {
    node: path ? state.TreeNodeReducer.tree[path] : {}
  };
}

2) видимо,ownProps Первый вызов подается с помощью встроенных реквизитов. Итак, вы можете позвонить<App /> таким образом вindex.js:

<App info={{ path:'/' }} />

Во всяком случае, после решения этой проблемы выдается еще одна ошибка (Cannot read property '/' of undefined) при попытке прочитатьtree от редуктора (там не существует).

у тебя должен быть только одинexport default за модуль. Но может иметь несколькоnamed export (без ключевого слова по умолчанию). mrlew
Пожалуйста. Может быть, кто-то знает лучшее решение. mrlew
После проверки кода я отредактировал ответ. Очевидно, ownProps не получает defaultProps. mrlew
Извините, я забыл обновить код, прежде чем публиковать ссылку, обновил только сейчас ... Mithril
12

Так какconnect() возвращает новый компонент. Если вы хотите, чтобы defaultProps присутствовал на нем, вам нужно добавить defaultProps:

App = connect(
  mapStateToProps,
  mapDispatchToProps
)(App);

App.defaultProps = {
  path:'/'
};

export default App

Это будет работать!

Установка defaultProps в компоненте контейнера ... отлично! mrlew

Похожие вопросы