【问题标题】:React - write and read nested objects in stateReact - 在状态下写入和读取嵌套对象
【发布时间】:2017-04-04 14:31:08
【问题描述】:

我正在开发一个 React 应用程序,该应用程序从 Google 的 Firebase 上的数据库中获取数据。

数据库是这样组织的:

users {
    user 1 {
        name
        surname
        ... 
    }
    user 2 {
        name
        surname
        ...
    }
}

我如何在 React 中检索数据:

我从 url 获取位置和工具来过滤搜索结果(现在只使用位置,但想同时使用两者),并且我成功地设法在控制台中打印了对象。

componentWillMount(){
    const searchResults = FBAppDB.ref('users');

    let location = this.props.location;
    let instrument = this.props.instrument;

    let profiles = [];
    searchResults.orderByChild('location').equalTo(location).on('value', (snap) => {
        let users = snap.val();
        Object.keys(users).map((key) => {
            let user = users[key];
            console.log(user);
            profiles.push(user);
        });
    });

    // this.setState({users: profiles[0]});
}

对象的控制台输出:

Object {name: "Whatever", surname: "Surrname", ... }

我似乎失败的是将这些对象(可能不止一个)保存在状态中,这样当用户更改页面上的其他过滤器时,我可以更新视图。

我试图 setState 实际用户,但状态结果为空,知道吗?

除了写入之外,从状态中获取数据的最佳方式是什么?如何循环遍历状态中的对象?

谢谢

编辑

这是我的渲染函数的样子:

render(){
    return(
        <Row>
            {
                Object.keys(this.state.users).map(function (key) {
                    var user = this.state.users[key];
                    return <SearchResult user={user} />
                })
            }
        </Row>
    );
}

我尝试直接打印 this.state.users,但它不起作用。因此,我试图提出一个(非工作)解决方案。对于这里的任何菜鸟错误,我深表歉意。

【问题讨论】:

  • 是否 SearchResult 期望 user 道具的格式为 { name: "Whatever", surname: "Surrname", ...}?
  • 是的,它需要整个对象,然后我像 this.props.user.name 这样调用每个属性

标签: javascript reactjs firebase firebase-realtime-database state


【解决方案1】:

尝试将 setState 放在 .on(() => ...) 中,紧跟在 Object.keys(...) 之后。这是对服务器的异步调用,对吧?我想 setState 是在调用服务器之后立即调用的,但在您检索任何数据之前。

【讨论】:

    【解决方案2】:

    我试图 setState 实际用户但状态结果为空,任何 想法?

    这是因为您的 DB 操作 searchResult异步,而 JavaScript 不会让 同步 代码等到异步代码完成。

    在您的代码中,如果您启用注释的 setState 调用,该代码将在异步代码等待响应时执行。

    你需要在setState里面:

    searchResults.orderByChild('location').equalTo(location).on('value', (snap) => {
        let users = snap.val();
        const profiles = Object.keys(users).map((key) => users[key]);
        this.setState({ users: profiles[0] });
    });
    

    如果您希望在异步代码之后执行某些操作,请将其放在 callback(到异步 fn)中或使用 Promise


    从该州取回数据的最佳方式是什么?如何循环遍历状态中的对象?

    setState 也可以是异步的。但是您将在下一次渲染时获得新的更新状态。因此,在render() 内部,您可以以this.state.users 的状态访问users,并使用它执行您的操作。

    更新:

    componentWillMount(){
        const searchResults = FBAppDB.ref('users');
        const location = this.props.location;
        const instrument = this.props.instrument;
    
        searchResults.orderByChild('location').equalTo(location).on('value', (snap) => {
            const users = snap.val();
            const profiles = Object.keys(users).map((key) => users[key]);
    
            // previously we were setting just profiles[0]; but I think you need 
            // the entire list of users as an array to render as search results
            this.setState({ users: profiles }); // set the whole data to state
        });
    }
    
    
    render(){
        const users = this.state.users || []; // note that this.state.users is an array
    
        return(
            <Row>
                {
                  users.length > 0 
                  ? users.map((user) => <SearchResult user={user} />)
                  : null
                }
            </Row>
        );
    }
    

    【讨论】:

    • 谢谢,第一部分效果很好!至于第二个,我想将保存在 this.state.users 中的每个对象作为渲染方法中 SearchResult 组件的道具传递。我没有设法遍历状态中的对象,知道吗?
    • 您能用render() 中的代码更新问题吗(您尝试在其中呈现 SearchResult 组件)?我仍然不清楚“循环遍历状态中的对象”的实际含义;你想达到什么目的?请更清楚地说明问题。
    • 请查看答案中的更新。让我知道这是否有效:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-08
    • 1970-01-01
    • 2020-11-13
    • 2021-09-03
    • 2018-10-12
    • 2020-07-31
    • 1970-01-01
    相关资源
    最近更新 更多