1

I using Meteor 1.3 for this application together with react js and Tracker React. I have a page to view all available users in the application. This page require user to login to view the data. If user not logged in, it will shows the login form and once logged-in the component will render the user's data.

Main component for the logic.

export default class MainLayout extends TrackerReact(React.Component) {
    
    isLogin() {
        return Meteor.userId() ? true : false
    }
    render() {
    
        if(!this.isLogin()){
            return (<Login />)
        }else{
        return (
            <div className="container">
                <AllUserdata  />            
            </div>
          )
        }
    }
}

And in the AllUserdata component:

export default class Users extends TrackerReact(React.Component) {

    constructor() {
        super();

        this.state ={
            subscription: {
                Allusers : Meteor.subscribe("AllUsers")
            }
        }

    }

    componentWillUnmount(){
        this.state.subscription.Allusers.stop();
    }

    allusers() {
        return Meteor.users.find().fetch();
    }

    render() {
        console.log('User objects ' + this.allusers());
        return (
                <div className="row">
                    {
                    this.allusers().map( (user, index)=> {
                            return <UserSinlge key={user._id} user={user} index={index + 1}/>
                            })
                     }

                        
                </div>
                
            )
    }   
};

The problem is when logged in, it only shows the current user's data. All other user objects are not rendered. If I check on the console, console.log('User objects ' + this.allusers()); show objects being rendered 3 times: the first render only shows the current user's data, the second one renders data for all users (the desired result), and the third one again renders only the current user's data.

If I refresh the page, the user data will be rendered properly.

Any idea why?

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
dev-jim
  • 2,404
  • 6
  • 35
  • 61
  • I have a very similar issue, and we have both followed the code pattern as exampled for TrackerReact (i.e. define a method in the class which returns the data from the subscribed collection, and then .map that in the render method). I see you've accepted an answer below, but it doesn't appear to resolve the problem, just tell you to do it some other way - which goes against the code pattern that TrackerReact shows in its own demo?! – Andy Lorenz Dec 08 '16 at 23:00

1 Answers1

1

React calls the render() method of components many times when it's running. If you're experiencing unexpected calls, it's usually the case that something is triggering changes to your component and initiating a re-render. It seems like something might be overwriting the call to Meteor.users.find().fetch(), which is probably happening because you're calling that function on each render. Try inspecting the value outside of the render method or, better yet, rely on tests to ensure that your component is doing what it should be :)

From https://facebook.github.io/react/docs/component-specs.html#render

The render() function should be pure, meaning that it does not modify component state, it returns the same result each time it's invoked, and it does not read from or write to the DOM or otherwise interact with the browser (e.g., by using setTimeout). If you need to interact with the browser, perform your work in componentDidMount() or the other lifecycle methods instead. Keeping render() pure makes server rendering more practical and makes components easier to think about.

See also:

markthethomas
  • 4,391
  • 2
  • 25
  • 38
  • I don't get it how can I inspecting the value outside the render method. My current solution is reload the page once user successfully logged-in. It is not the perfect, but it is only thing that I can come up with at the moment. – dev-jim Apr 21 '16 at 06:10
  • You could easily inspect data in a custom method or in any one of the lifecycle methods (although not all would be necessarily give you what you'd be looking for). The best way to do it would be through the React devtools -> https://github.com/facebook/react-devtools – markthethomas Apr 21 '16 at 06:57