【问题标题】:Component only rending if I start the flow from the homepage仅当我从主页启动流程时组件才会渲染
【发布时间】:2019-05-27 12:10:16
【问题描述】:

我的申请有问题。我的用户组件仅在我从主页启动应用程序然后单击那里的用户链接时才加载 UserCard ...如果我只是刷新用户 URL ... UserCard 没有被加载,这意味着我的this.props.users 有问题。我确实在 chrome 中看到它说:Value below was evaluated just now 当我刷新但当我通过流程时它并没有这么说。任何帮助将不胜感激。

App.js

class App extends Component {
    constructor(props) {
        super(props);

        this.state = {
            users: []
        };
    }

    componentDidMount() {
        users = []
        axios.get('/getall').then((res) => {
            for(var d in res.data) {
                users.push(new User(res.data[d]));
            }
        });
    this.setState({ users });
    }

    render() {
        const { users } = this.state;
        return (
            <Router history={history}>
                <Switch>
                    <PrivateRoute exact path="/" component={Home} />
                    <Route exact path='/users' render={(props) => <Users {...props} users={users} />}/>
                </Switch>
            </Router>
        )
    }
}

私人路线:

export const PrivateRoute = ({ component: Component, ...rest }) => (
    <Route {...rest} render={props => (
        <Component {...props} /> )} />
)

用户.js

export default class Users extends Component {
    render() {
        console.log(this.props.users);
        return (
            <Row>
                {this.props.users.map(u =>
                        <UserCard key={u.name} user={u}/>
                )}
            </Row>
        );
    }
}

export class User {
    constructor(obj) {
        for (var prop in obj){
            this[prop] = obj[prop];
        }
    }

    getURLName() {
        return this.name.replace(/\s+/g, '-').toLowerCase();
    }
}

class UserCard extends Component {

    render() {
        return (
            <Link to={'/users/' + this.props.user.getURLName()} >
                <div>
                    // Stuff Here
                </div>
            </Link>
        );
    }
}

【问题讨论】:

  • 您正在直接在componentDidMount 中修改this.state。你应该使用this.setState。 (这可能是您的问题出现的地方)。可能不相关,但您还提供了 &lt;UserCard /&gt;user 道具,然后您在 UserCard 内引用 this.props.users.getURLName() (不应该是 this.props.user.getURLName() 吗?这可能只是问题中的一个错字,因为那会运行您的应用程序时很快就会出错。)
  • @StuartBourhill 第二点是错字。我也使用 this.setState 但结果相同。只有当我完成整个流程时,才会在页面刷新时调用 UserCard
  • 更新了相关代码以反映它
  • 这里有一些非常粗略的东西。只能使用 this.setState 来修改状态。如果必须,let x = this.state.x; dothingsto(x); this.setState({ x });。另外,不要批发重新绑定this[prop] = obj[prop],你所有的代码都在说“我没有正确编写我的用户类并且使调试变得异常困难,因为我不知道哪些函数和属性应该是可调用的”。最后,您可能希望将该 UserCare 转换为 function(props) { return &lt;Link .... &gt;; },而不是一个类,因为您不会以任何方式依赖那里的状态。
  • 您能否也为您的主路由和用户路由显示相关的 react-router 位?因为这些决定了运行的确切内容。

标签: javascript arrays reactjs object react-redux


【解决方案1】:

根据 cmets:

这里的问题是您如何设置状态。你不应该直接修改状态,因为这不会导致组件重新渲染See the react docs

一些与问题无关的额外想法:

  • 根据 cmets - 尽可能使用函数组件,尤其是在使用 hooks
  • 可能不需要创建User 类,只需创建new 小用户对象即可。只需使用普通的旧 JS 对象并在其使用的位置计算链接 url:

render() {
  const { user } = this.props
  return <Link to={`/users/${user.name.replace(/\s+/g, '-').toLowerCase()}`} />
}
  • 开始使用 eslint 之类的 linter 可能是个好主意。我看到您在声明 users = [] 时没有使用 letconst(不要使用 var)。这是不好的做法,因为以这种方式创建变量会污染全局名称空间。像 eslint 这样的 Linter 将帮助您在编码时发现此类问题。

【讨论】:

  • 功能组件有什么好处?
猜你喜欢
  • 2019-01-26
  • 2022-01-06
  • 1970-01-01
  • 2023-01-07
  • 2020-07-16
  • 2013-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多