回调渲染器丢失了路由器上下文for child react-router&终极版

时间:2017-02-08 19:36:34

标签: javascript redux react-router react-router-redux

我一直在制定一个想法,但我遇到了一些不寻常的事情(我的大脑在反应路由器上受伤)。

我正在尝试使用返回的对象(多个类似对象)中的.map动态呈现项目列表,并将它们附加到render(){return(<div />)}

我只是不知道另一种方式,而不是调用函数然后.map这个回调的结果。

我认为我这样做的方式意味着渲染的项目会失去上下文。 react-router <Link />将在正常流程中(在render(){return(<div />)}内部)正常运行,但在从渲染外部创建项目时则不会。我在代码下方发布了错误。

我已经阅读了很多不同的方法来解决这个问题,使用上下文和位置/历史以及withRouter。坦率地说,我输了。

如果有人能够查看下面的示例并指导我朝着正确的方向前进,我将不胜感激。

一些注意事项: - 主要焦点似乎是在mystuff中 - 我知道有很多不必要的进口产品 - 为了清晰而被剥离,否则我会迷失方向

索引

import _ from 'lodash';
import React from 'react';
import { render } from 'react-dom';
import { Router, Route, IndexRoute, browserHistory } from 'react-router';
import { Provider } from 'react-redux';
import { store, history } from './store';

import Main from './Main';
import { routyr } from './Menu';

// remaining paths in Menu.js (routyr) for menu visibility
const router = (
  <Provider store={store}>
    <Router history={history}>
      <Route path="/" component={Main}>
        {routyr}
      </Route>
    </Router>
  </Provider>
)

render (router, document.getElementById('app'));

主要

import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as actionCreators from './actionCreators';

import App from './app';

function mapStateToProps(state){
  return{
    info: state.info,
    myProfile: state.myProfile
  }
}

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

const Main = connect(mapStateToProps, mapDispatchToProps)(App);
export default Main;

routyr

import React from 'react';
import { Link } from 'react-router';
import { Router, Route, IndexRoute, browserHistory } from 'react-router';
import { Provider } from 'react-redux';

import { store, history } from './store';

//pages
import App from './app';
import Landing from './Landing';
import Me from './mystuff';
import ViewStuff from './viewStuff';

//Routes for index.js
export const routyr = (
  <span>
    <IndexRoute component={Landing} />
    <Route path="/myStuff" component={Me} />
    <Route path="/viewStuff" component={ViewStuff} />
  </span>
)

//Menu types
//loaded by app.js
export const menuLoggedIn = (
  <div className="MainMenu">
    <Link to='/' className="buttonA green">Home</Link>
    <Link to='myStuff' className="buttonA green">My Stuff</Link>
  </div>
);
export const menuLoggedOut = (
  <div className="MainMenu">
    <Link to='/login' className="buttonA green">Login</Link>
  </div>
);

应用

import React from 'react';
import _ from 'lodash';
import { Link } from 'react-router';
import auth from './auth';
import Landing from './Landing';
import Header from './Header';
import { menuLoggedIn, menuLoggedOut } from './Menu';

export default class App extends React.Component {
  constructor(){
    super();
    this.state={
      auth: auth.loggedIn(),
      menu: null
    };
  }

  componentWillMount(){
    if (this.state.auth==true) {
      this.setState({
        menu: menuLoggedIn
      })
    }else{
      this.setState({
        menu: menuLoggedOut
      });
    }
  }

  render(){
    return (
      <div>
        <Header />
        {this.state.menu}<br />
        <div id="view">
          {React.cloneElement(this.props.children, this.props)}
        </div>
      </div>
    );
  }
};

的MyStuff

import React, { PropTypes } from 'react';
import { render } from 'react-dom';
import { Link } from 'react-router';
import { withRouter } from 'react-router';
import { Provider } from 'react-redux';

import * from './whacks';

export default class Me extends React.Component{
  constructor(){
    super();
  }
  componentDidMount() {

    function listThem(oio){
      oio.map(function(ducks){
        render(

          <div className="ListItem">
            <Link to="/viewStuff"> _BROKEN_ View Stuff</Link>
            <div className="listLabel">{ducks.type}</div>
            <h3>{ducks.description.title}</h3>
            {ducks.description.long}
          </div>, document.getElementById('fishes').appendChild(document.createElement('div'))

        );
      });
    }

    var some = new Whacks();

    some.thing(more, (close, open) => {

      if(close){
        console.log(close));
      } else {
        doIt(open);
      }

    });
  }

  render(){
    return(
      <div>
        <Link to="viewStuff"> _WORKING_ View Stuff</Link>
        <div id="fishes">
        </div>
      </div>
    )
  }
}

存储

import { createStore, compose } from 'redux';
import { syncHistoryWithStore } from 'react-router-redux';
import { browserHistory } from 'react-router';
import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';

/*-------ROOT REDUCER---------*/
/*-------DEFAULT STATES---------*/
/*-------CREATE STORE---------*/
/*-------INTEGRATE HISTORY---------*/

import me from './reducers/obj';
import myProfile from './reducers/myProfile';

const rootReducer = combineReducers(
  {
    routing: routerReducer,
    me,
    myProfile
  }
);

//TEMP remove harcoded var
const uuidSet = "fa78d964";
export const defaultState = {
  uuid: uuidSet,
};

export const store = createStore(rootReducer, defaultState, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());
export const history = syncHistoryWithStore(browserHistory, store);

actionCreators

export function me (obj){
  return {
    type: "ADD_OBJECTLIST",
    obj
  }
}

export function myProfile (dump){
  return {
    type: "MY_DATA",
    dump
  }
}
来自package.json的

"react-redux": "^5.0.2",
"react-router": "^3.0.2",
"react-router-redux": "^4.0.7",
"redux": "^3.6.0",

错误

  

未捕获错误:在路由器上下文之外呈现的无法导航。

@UG, 我在mystuff中尝试了以下内容:

constructor(){
  super();
  this.state={
    oio: {}
  };
}

some.thing(more, (close, open) => {

      if(close){
        console.log(close));
      } else {
        this.setState({
          oio: open
        });
      }

});

render(){
  let flat = this.state.oio;
  flat.map(function(ducks){
    return (
      <div className="ListItem">
        <Link to="/viewStuff">View Stuff</Link>
        <div className="listLabel">{ducks.type}</div>
        <h3>{ducks.description.title}</h3>
        {ducks.description.long}
      </div>
    )
  })
}

并收到

  

未捕获的TypeError:flat.map不是函数       在Me.render

2 个答案:

答案 0 :(得分:1)

我不确定我是否完全解决了您的问题。但我认为你想在render()的{​​{1}}方法中使用Link 您可以将其更改为以下内容:

myStuff

根据詹姆斯的评论,

您应该使用react状态来维护oio对象。

render(){
return(
  <div>
    <Link to="viewStuff"> _WORKING_ View Stuff</Link>
    <div id="fishes">
        {
            oio.map(function(ducks){
                return (
                    <div className="ListItem">
                        <Link to="/viewStuff"> _BROKEN_ View Stuff</Link>
                        <div className="listLabel">{ducks.type}</div>
                        <h3>{ducks.description.title}</h3>
                        {ducks.description.long}
                    </div>
                );
            }
    </div>
  </div>
    )
}

并在异步调用中更新状态,当状态更新时,组件可以重新呈现。

答案 1 :(得分:0)

非常感谢UG_用状态打我的耳朵。 我已经拉入了一个组件并从回调对象中创建了每个组件的道具。 我的工作解决方案如下:mystuff:

constructor(props){
  super(props);
  this.state={
    oio: []
  }
}
componentDidMount() {

  let listThem = (stuff) => {
    let ioi = [];
    stuff.forEach(function(dood, index, array) {
      let lame = <MyItem plop={dood} key={index} />;
      ioi.push(lame);
    });
    return (
      this.setState({
        oio: ioi
      })
    );
  }

  var some = new Whacks();
  some.thing(more, (close, open) => {
    if(close){
      console.log(close));
    } else {
      listThem(open);
    }
  });

}
render(){
  return(
    <div>
      {this.state.oio}
    </div>
  )
}

使用每个返回对象的道具呈现MyItem组件的新副本。所以现在我的返回项目包含上下文!