简体   繁体   中英

Components gets the wrong props when clicking links in React-router

I'm working on a simple User page where each user has their own profile. The profile page works on initial load.

However, if I am currently viewing the profile of user1 then click a link to take me to user2 , the profile page will still load user1 because this.props.params haven't updated yet. If I click the link twice, then the profile of user2 will show up. I need help getting this to work correctly

Here, code speaks more than words:

var { Router, Route, Redirect, IndexRoute, IndexLink, Link, hashHistory, browserHistory } = ReactRouter;
var browserHistory = ReactRouter.browserHistory;


var Profile = React.createClass({
    getInitialState: function() {
        return {
            userName: '',
            userId: '',
            displayName: ''
        };
    },
    setProfile: function() {
        $.post('/api/v1/rest/getUser', {username: this.props.params.name}, function (result) {
            if(!result.error) {
                this.setState({
                    userName: result.seo_name,
                    userId: result.member_id,
                    displayName: result.display_name
                });
            }
        }.bind(this));
    },
    componentDidMount: function() {
        this.setProfile();
    },
    componentWillReceiveProps: function() {
        this.setProfile();
    },
    render: function() {
        return (
            <div>
                {this.state.displayName}
            </div>
        );
    }
});

var MainLayout = React.createClass({
    render() {
        return (
            <div className="application">
                <header>
                    {this.props.children.props.route.title}
                </header>
                <nav>
                    <Link to="/profile/user1">User 1</Link>
                    <Link to="/profile/user2">User 2</Link>
                </nav>
                {this.props.children}
            </div>
        )
    }
});

ReactDOM.render((
    <Router history={ReactRouter.browserHistory}>
        <Route component={MainLayout}>
            <Route name="profile" path="/profile/:name" title={'Viewing profile'} component={Profile} />
        </Route>
    </Router>
), document.getElementById('application'));

As you can see I'm using jquery for ajax calls, and I've added two links for testing in the nav of the MainLayout component. Every time I go to a new profile, I want to re-run the ajax call and fetch new profile information instantly.

Another short question: Inside the MainLayout component, I'm printing the title of the page in the header using props defined on the Route element ( this.props.children.props.route.title ). This currently says "Viewing profile". I want it to say "Viewing profile of Username", where Username is a variable. I couldn't figure out a clean react way to do this (appending something to the title of a parent component).

here two suggestions:

  1. name it getProfile instead of setProfile ..
  2. getProfile function should take a param, and not rely on the context ;)

Solution:

componentWillReceiveProps means new props are going to be set.. so they are not set yet. However nextProps are available.

componentDidMount: function() {
  // use the name from props to get the profile
  this.getProfile(this.props.params.name)
}    

componentWillReceiveProps: function(nextProps) {
  // use the name from nextProps to get the profile
  this.getProfile(nextProps.params.name);
},

getProfile: function(name) {
    // ajax call, use the *name* param
}
  1. Question about the title

There is a component called Helmet, its specially to change those things like title

https://github.com/nfl/react-helmet

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM