【问题标题】:use ReactJS to .map through response of Express API通过 Express API 的响应使用 ReactJS 映射到 .map
【发布时间】:2017-08-20 01:27:50
【问题描述】:

我有一个 Express API,它在安装 reactJS 组件时收到请求时响应来自 MongoDB 的数据。

app.get('/api/characters', function(req, res) {
  var db = req.db;
  var collection = db.get('usercollection');
  collection.find({},{},function(e,docs){
    res.send({
      data: docs
    });
  });
});

字符组件代码

export default class Characters extends React.Component {

    constructor(props) {
    super(props);
    this.state = CharactersStore.getState();
    this.onChange = this.onChange.bind(this);
    }
    componentDidMount() {
        CharactersStore.listen(this.onChange);
        CharactersActions.getCharacters('http://localhost:3000/api/characters');
    }
    componentWillUnmount() {
      CharactersStore.unlisten(this.onChange);
    }
    onChange(state) {
    this.setState(state);
  }
    render() {
        return (
            <section>
            <div className="container">
              <div className="row">
                <h2 className="text-center">{this.props.route.header}</h2>
                <hr className="star-light"/>
                <CharacterList data={this.state.characters}/>
              </div>
            </div>
            </section>
        )
    }
}

字符组件操作代码

class CharactersActions {
  constructor() {
    this.generateActions(
      'getCharactersSuccess',
      'getCharactersFail'
    );
  }
  getCharacters(query) {
    requestPromise(query)
      .then((res) => {
        this.actions.getCharactersSuccess(res)
      }).catch((err) => {
        console.log('error:', err);
        this.actions.getCharactersFail(err)
      })
  }
}

export default alt.createActions(CharactersActions);

字符组件存储

的代码
class CharactersStore {
  constructor() {
    this.bindActions(CharactersActions);
    this.characters = [''];
    this.isLoading = true;
  }
  getCharactersSuccess(res) {
    this.characters = res;
    this.isLoading = false;
  }
  getCharactersFail(err) {
    toastr.error(err.responseJSON && err.responseJSON.message || err.responseText || err.statusText);
  }
}

export default alt.createStore(CharactersStore);

上面的 Characters 组件在挂载时请求 API,并将响应数据发送到 store 以保存到 State。

然后我将 Characters 状态作为道具(命名数据)传递给子组件 CharacterList

字符列表组件

export default class CharacterList extends React.Component {

    constructor(props) {
    super(props);
    }

    render() {

        return (
        <div className="col-lg-3 col-sm-6">

        {console.log(this.props.data)}

        // THIS IS WHERE I AM TRYING TO .MAP THROUGH THE RESULTS

    </div>
        )
    }
}

我正在尝试使用 .map 循环遍历返回的数据,但有点不确定如何继续,任何建议都将不胜感激。数据返回如下:

{
  "data": [
    {
      "_id": "58d5044b0898f816066227f1",
      "character": "Luke Skywalker"
    },
    {
      "_id": "58d504c60898f816066227f2",
      "character": "Obi Wan Kenobi"
    },
    {
      "_id": "58d504c60898f816066227f3",
      "character": "Han Solo"
    }
  ]
}

【问题讨论】:

    标签: mongodb reactjs express


    【解决方案1】:

    这很简单。我不知道你在哪里混淆了。试试这个

    <div className="col-lg-3 col-sm-6">
    
    {
        Array.isArray(this.props.data)&& this.props.data.map((val,index)=>{
              return val
            })
    }
     </div>
    

    【讨论】:

    • 嗯,这是我认为我需要的,我对结果中的初始“数据”数组有点困惑。我试过使用你的代码,但得到 this.props.data.map is not a function
    • 这是因为,this.props.data 在初始渲染时没有定义。
    【解决方案2】:

    您想将res.data 设置为您的characters 存储。

    getCharactersSuccess(res) {
      this.characters = res.data; // <--
      this.isLoading = false;
    }
    

    然后您可以映射 data 数组,而不是完整的响应:

    const data = [
      {
        _id: '58d5044b0898f816066227f1',
        character: 'Luke Skywalker'
      },
      {
        _id: '58d504c60898f816066227f2',
        character: 'Obi Wan Kenobi'
      },
      {
        _id: '58d504c60898f816066227f3',
        character: 'Han Solo'
      }
    ];
    
    const Character = ({ data }) => <div>{data.character}</div>;
    
    class CharacterList extends React.Component {
      render() {
        return (
          <div>
            {this.props.data.map((character, i) => (
              <Character key={i} data={character} />
            ))}
          </div>
        );
      }
    }
    
    ReactDOM.render(<CharacterList data={data} />, document.getElementById('root'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    <div id="root"></div>

    【讨论】:

    • 我尝试在发布问题之前将 .data 添加到我的角色状态,这似乎返回 NULL
    • 似乎返回空值?你能检查一下是不是真的吗?
    • 就个人而言,我喜欢在映射这样的数组时使用扩展运算符,例如&lt;Character key={i} {...character} /&gt;。这样,您在使用值时不需要额外的层,例如const Character = ({ character }) =&gt; &lt;div&gt;{character}&lt;/div&gt;.
    • @MichaelPeyper 好建议!但我不能确定 OP 是否使用了 babel-stage-3 预设,否则代码将失败并导致进一步的问题。
    • @FabianSchultz - 确认它返回为“未定义”
    猜你喜欢
    • 1970-01-01
    • 2017-04-09
    • 2019-06-21
    • 1970-01-01
    • 2018-05-14
    • 2021-05-23
    • 2021-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多