admin管理员组

文章数量:1313794

I am creating a basic blog in react using Flux + React Router + Firebase. I am having trouble trying to get a single blog post to render. When I click on the link to a single post, I try to filter out all of the other posts from a list of all posts and display only a single post from my firebase database.

I attempt to do this by matching the key of the firebase entry with the url params like so if (this.props.routeParams.key===key) . I really do not know what I have to do to make this happen. Any suggestions are wele.

Below is Blogger.jsx, the page where I allow a user to create a blog post and then beneath the blog post, I display a list of the titles all blog posts.

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 = '/';



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

    };


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

  ponentWillMount() {
    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>



    );
  }

}

When a user clicks on a link to a single blog post, they should be transported to a page which shows only that single blog post. I have called this ponent BlogShow. I can't get BlogShow to render because I keep on getting the error

invariant.js?4599:45 Uncaught Invariant Violation: BlogShow.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.

This is 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 = '/';

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>


  }

}

I am creating a basic blog in react using Flux + React Router + Firebase. I am having trouble trying to get a single blog post to render. When I click on the link to a single post, I try to filter out all of the other posts from a list of all posts and display only a single post from my firebase database.

I attempt to do this by matching the key of the firebase entry with the url params like so if (this.props.routeParams.key===key) . I really do not know what I have to do to make this happen. Any suggestions are wele.

Below is Blogger.jsx, the page where I allow a user to create a blog post and then beneath the blog post, I display a list of the titles all blog posts.

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./';



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

    };


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

  ponentWillMount() {
    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>



    );
  }

}

When a user clicks on a link to a single blog post, they should be transported to a page which shows only that single blog post. I have called this ponent BlogShow. I can't get BlogShow to render because I keep on getting the error

invariant.js?4599:45 Uncaught Invariant Violation: BlogShow.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.

This is 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./';

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>


  }

}
Share Improve this question asked May 1, 2016 at 16:34 CodeYogiCodeYogi 1,3993 gold badges12 silver badges14 bronze badges 3
  • You should use .filter() and not .map(). Otherwise they will be set to undefined instead of being removed from the array. – castletheperson Commented May 1, 2016 at 16:41
  • How would I do this? Can you please provide an example of what this would look like? – CodeYogi Commented May 1, 2016 at 16:43
  • I changed it to this and still now luck: <div> {Object.keys(BlogStore.state.blog).filter(this.filterList)} </div> – CodeYogi Commented May 1, 2016 at 16:45
Add a ment  | 

2 Answers 2

Reset to default 5

You are getting that error because your Component BlogShow is not returning anything.

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

Should be:

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

I'm not familiar with React.js at all, but I am familiar with pure JS arrays. To remove elements from an array, you should use .filter(), and then afterwards you can map the items.

Something like this:

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

本文标签: javascriptFiltering List in ReactStack Overflow