React JS 组件在 Meteor 中多次渲染

React JS component renders multiple times in Meteor

我将 Meteor 1.3 与 React js 和 Tracker React 一起用于此应用程序。 我有一个页面可以查看应用程序中的所有可用用户。此页面需要用户登录才能查看数据。如果用户未登录,它将显示登录表单,一旦登录,组件将呈现用户数据。

逻辑的主要组成部分。

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>
          )
        }
    }
}

并且在 AllUserdata 组件中:

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>
                
            )
    }   
};

问题是登录后,只显示当前用户的数据。不会呈现所有其他用户对象。如果我在控制台上查看,console.log('User objects ' + this.allusers()); 显示对象被渲染 3 次:第一次渲染只显示当前用户的数据,第二次渲染所有用户的数据(期望的结果),第三次再次渲染只当前用户的数据。

如果我刷新页面,用户数据将正确呈现。

知道为什么吗?

React 在 运行 时多次调用组件的 render() 方法。如果您遇到意外调用,通常是某些事情触发了组件更改并启动了重新渲染。似乎某些东西可能正在覆盖对 Meteor.users.find().fetch() 的调用,这可能是因为您在每个渲染器上调用该函数。尝试检查 render 方法的 outside 值,或者更好的是,依靠测试来确保您的组件正在做它应该做的事情:)

来自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.

另请参阅: