【问题标题】:Filtering List in ReactReact 中的过滤列表
【发布时间】:2016-08-26 10:18:00
【问题描述】:

我正在使用 Flux + React Router + Firebase 创建一个基本博客。我在尝试获取单个博客文章来呈现时遇到了麻烦。当我单击单个帖子的链接时,我尝试从所有帖子列表中过滤掉所有其他帖子,并仅显示我的 firebase 数据库中的单个帖子。

我尝试通过将 firebase 条目的键与 url 参数匹配来做到这一点,例如 if (this.props.routeParams.key===key) 。我真的不知道我必须做些什么才能做到这一点。欢迎任何建议。

下面是 Blogger.jsx,我允许用户创建博客文章的页面,然后在博客文章下方,我显示所有博客文章的标题列表。

import AltContainer from 'alt-container';
import React from 'react';
import { Link } from 'react-router';
import List from './List.jsx'
import Firebase from 'firebase'
import BlogStore from '../stores/BlogStore'
import BlogActions from '../actions/BlogActions';


const rootURL = 'https://incandescent-fire-6143.firebaseio.com/';



export default class Blogger extends React.Component {
  constructor(props) {
    super(props);
    BlogStore.getState();
    BlogStore.mountFirebase();
    {console.log(this.props.location.query)}

    };


  componentDidMount() {
    BlogStore.listen((state) => {
      this.setState(state)
    })
    this.firebaseRef = new Firebase(rootURL + 'items/');
  }

  componentWillMount() {
    BlogStore.unlisten((state) => {
      this.setState(state)
    })
  }




  renderList = (key) => {
      return (
      <Link to={`blogshow/${key}`}> <List key={key} blog={this.state.blog[key]} /> </Link>
      )
    }


  handleInputChange = () => {

    BlogStore.setState({
      title: this.refs.title.value,
      text: this.refs.text.value});
  }


  handleClick = () => {

    BlogStore.handleClick();
  }


  render() {
    return (
      <div>
        <div className="row panel panel-default">
          <div className="col-md-8 col-md-offset-2">
            <h2>
                Create a New Blog Post
            </h2>
          </div>
        </div>

<h2>Blog Title</h2>
        <div className="input-group">
          <input
          ref="title"
          value={BlogStore.state.title}
          onChange = {this.handleInputChange}
          type="text"
          className="form-control"/>
          <span className="input-group-btn">

          </span>
        </div>

<h2>Blog Entry</h2>
        <div className="input-group">
          <textarea
          ref="text"
          value={BlogStore.state.text}
          onChange = {this.handleInputChange}
          type="text"
          className="form-control"/>

        </div>

        <div className="blog-submit input-group-btn">
          <button onClick={this.handleClick}
          className="btn btn-default" type="button">
            Publish Blog Post
          </button>
        </div>

        {/*<List blog={this.state.blog} />*/}

        {Object.keys(BlogStore.state.blog)
       .map(this.renderList)}



    </div>



    );
  }

}

当用户单击指向单个博客文章的链接时,他们应该被传送到仅显示该单个博客文章的页面。我称这个组件为 BlogShow。我无法让 BlogShow 呈现,因为我不断收到错误

invariant.js?4599:45 未捕获的不变违规:BlogShow.render():A 必须返回有效的 React 元素(或 null)。您可能已经返回 未定义、数组或其他一些无效对象。

这是 BlogShow.jsx:

import AltContainer from 'alt-container';
import React from 'react';
import { Link } from 'react-router';
import Blogger from './Blogger'
import List from './List'
const rootURL = 'https://incandescent-fire-6143.firebaseio.com/';

import BlogStore from '../stores/BlogStore'
import BlogActions from '../actions/BlogActions';



export default class BlogShow extends React.Component {
  constructor(props) {
    super(props);
    {console.log(this.props.routeParams.key)}
    this.filterList = this.filterList.bind(this);

}



filterList(key) {
  if (this.props.routeParams.key===key) {
    return (<List key={key} blog={BlogStore.state.blog[key]} />)
  }
}

  render() {

             <div> {Object.keys(BlogStore.state.blog).map(this.filterList)} </div>


  }

}

【问题讨论】:

  • 您应该使用.filter() 而不是.map()。否则它们将被设置为undefined,而不是从数组中删除。
  • 我该怎么做?你能举个例子说明一下吗?
  • 我把它改成了这个,现在仍然很幸运:
    {Object.keys(BlogStore.state.blog).filter(this.filterList)}

标签: javascript reactjs firebase react-router


【解决方案1】:

我完全不熟悉 React.js,但我熟悉纯 JS 数组。要从数组中删除元素,您应该使用.filter(),然后您可以映射这些项目。

类似这样的:

filterList(key) {
  return this.props.routeParams.key === key; // true if the item should stay in the list
}

mapList(key) {
  return <List key={key} blog={BlogStore.state.blog[key]} />;
}

render() {
  return <div> {Object.keys(BlogStore.state.blog).filter(this.filterList).map(this.mapList)} </div>;
}

【讨论】:

  • 我不知道 React.js 是否预编译 JS,但我认为让 filterList 自己坐在那里是不正确的语法。我认为它应该是function filterList(key),然后它应该被称为filterList 而不是this.filterList。我可能是错的。如果我不是,请有人编辑。
  • 谢谢@4castle。这让我更近了一步。我仍然收到同样的错误,但至少我了解我想要做得更好的背后的纯 JavsScript。
  • @4castle 错误是由返回状态引起的,你甚至不需要那里的过滤器。
  • @QoP 是的。但是如果他们想过滤,这就是它的完成方式。
  • @4castle 不是,如果你返回 null,React 不会渲染任何东西,所以完全没问题。
【解决方案2】:

您收到该错误是因为您的组件 BlogShow 没有返回任何内容。

render() {
    <div> {Object.keys(BlogStore.state.blog).map(this.filterList)} </div>
}

应该是:

render() {
    return <div> {Object.keys(BlogStore.state.blog).map(this.filterList)} </div>
}

【讨论】:

  • 谢谢@4castle。您的回答也已集成到我的解决方案中。
猜你喜欢
  • 1970-01-01
  • 2017-09-24
  • 1970-01-01
  • 1970-01-01
  • 2021-04-10
  • 2019-01-24
  • 1970-01-01
  • 2019-02-01
  • 1970-01-01
相关资源
最近更新 更多