Javascript 为反应组件设置默认道具

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38004703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 20:58:18  来源:igfitidea点击:

Set default props for a react Component

javascriptreactjsecmascript-6redux

提问by Mithril

I want my app component has a default props , and use that props in mapStateToProps.

我希望我的应用程序组件有一个默认的 props ,并在 mapStateToProps.

containers/App.js

容器/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);

reducers/TreeNodeReducer.js

减速器/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;
  }
}


I have tried :

我试过了 :

1: constructor

1:构造函数

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

2: defaultProps:

2:默认道具:

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

but none of them work... log always is:

但他们都没有工作......日志总是:

enter image description here

在此处输入图片说明

statehas the correct default value, but ownPropsis empty...

state具有正确的默认值,但ownProps为空...

PS:Project is here .

PS:项目在这里

采纳答案by mrlew

1) two "export default"

1)两个“出口默认”

you're doing two export defaultinto App.js.

你做了两export defaultApp.js

Try changing:

尝试改变:

export default class App extends Component

export default class App extends Component

to

const App = class App extends Component.

const App = class App extends Component.

And then:

进而:

...

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

2) "defaultProps" and "ownProps":

2)“defaultProps”和“ownProps”:

As mapStateToPropsis being called before the component construction (when defaultProps are defined), the ownPropsis empty. You can try two options:

作为mapStateToProps在部件施工前被调用(defaultProps被定义时),则ownProps是空的。您可以尝试两种选择:

1) this workaround:

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) apparently, ownPropsfirst call is feeded with the inline defined props. So, you can call <App />this way in the index.js:

2)显然,ownProps第一个调用是用内联定义的道具提供的。所以,你可以调用<App />这样的index.js

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

Anyway, after solving this, another error is thrown (Cannot read property '/' of undefined) when trying to read treefrom the reducer (doesn't exist there).

无论如何,解决此问题后,Cannot read property '/' of undefined尝试tree从减速器读取时会引发另一个错误 ( ) (那里不存在)。

回答by Mithril

I found a better way to set defaultProps,

我找到了一个更好的方法来设置 defaultProps,

Because connect()returns a new component. If you'd like defaultProps to be present on it, you need to put defaultProps on it:

因为connect()返回一个新组件。如果您希望 defaultProps 出现在其上,则需要将 defaultProps 放在其上:

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

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

export default App

This would work!

这行得通!