2017-05-18 8 views
0

Ich bin neu in React und Redux und versuche, Posts aus der WordPress-REST-API zu laden und sie in meiner React App anzuzeigen.So zeigen Sie geladene Posts mit React und Redux an

Ich benutze dies als Beispiel: https://github.com/jackreichert/a-wp-react-redux-theme

Meine Aktion die Pfosten so aussehen zu bekommen:

import axios from 'axios'; 
export const FETCH_POSTS = 'FETCH_POSTS'; 

export function fetchPosts(post_type = 'posts') { 
    return function (dispatch) { 
     axios.get(`http://localhost:8080/wp-json/wp/v2/${post_type}`) 
      .then(response => { 
       dispatch({ 
        type: FETCH_POSTS, 
        payload: response.data 
       }); 
      }); 
    } 
} 

Es ist auf die Reduzierung übergeben, die wie folgt aussieht:

import { FETCH_POSTS } from '../actions'; 

export default (state = [], action) => { 
    switch (action.type) { 
     case FETCH_POSTS: 
      return action.payload; 
     default : 
      state = ''; 
     break; 
    } 
    return state; 
} 

Und (obwohl es nur ein Reduzierer ist) kombiniere ich es, weil es mehr Reduzierer zu folgen gibt (genau wie im Beispiel), und dann ich es speichern werde. Genauso wie das Beispiel.

Im Laden alles in meiner Home.jsx-Datei, die jetzt wie dieses Recht aussieht:

import React, { Component } from 'react'; 
import {connect} from 'react-redux'; 
import { Link } from 'react-router-dom'; 

import Header from '../Header'; 
import {fetchPosts} from '../../actions/'; 

class Home extends Component{ 
    componentDidMount(){ 
     document.title = 'Test'; 
    } 

    componentWillMount() { 
     this.getPosts(this.props, true); 
    } 

    componentWillReceiveProps(nextProps) { 
     this.getPosts(nextProps); 
    } 

    getPosts(props, willMount = false) { 
     if (willMount) { 
      this.props.fetchPosts(); 
     } 
    } 
    render() { 
     return(
      <div> 
       <Header/> 
       <main> 
        <h1>Home</h1> 
       </main> 
      </div> 
     ) 
    } 
} 

function mapStateToProps({posts}) { 
    return {posts}; 
} 

export default connect(mapStateToProps, {fetchPosts})(Home); 

Ich glaube, mein Code oben rechts ist. Redux kann auch ‚finden‘ meine Beiträge und Protokolle in meiner Konsole:

action FETCH_POSTS @ 11:11:56.393 
    prev state Object {posts: ""} 
    action  Object {type: "FETCH_POSTS", payload: Array(2)} 
    next state Object {posts: Array(2)} 

Jetzt möchte ich wissen: Wie kann ich einfach die Beiträge angezeigt werden, die von Redux geladen werden, in meiner Home.jsx Datei. Und danach: Wie kann ich die Route und die Daten konfigurieren, um zu einem einzigen Beitrag zu gehen (aber das wird später kommen, für jetzt möchte ich nur eine einfache, aber richtige Weise wissen, wie die Beiträge anzuzeigen)

Antwort

1

Ich habe keine Ahnung von der Struktur Ihres Post-Objekts. Aber so sollte es sein.

renderPosts() { 
    return _.map(this.props.posts, post => { 
    return (
     <li className="list-group-item" key={post.id}> 
      {post.title} 
     </li> 
    ); 
    }); 
} 

Dann in Ihrer Render-Methode einfach so nennen.

render() { 
    return (
     <div> 
     <h3>Posts</h3> 
     <ul className="list-group"> 
      {this.renderPosts()} 
     </ul> 
     </div> 
    ); 
    } 

Beachten Sie auch, dass ich map Helfer aus lodash Bibliothek hier verwenden. Sie müssen also die folgende import-Anweisung in Ihrer Komponente haben.

import _ from 'lodash'; 

Hoffe das hilft. Glückliche Kodierung!

+0

Das ist hilfreich, funktioniert aber leider nicht .. Ich habe meine Frage aktualisiert. Ich hoffe du verstehst wie ich es erklärt habe, hahahaha – coder14

+0

NEVERMIND! Es funktioniert! – coder14

+0

Vielleicht wäre es das Beste für Sie, Ihre Frage zu bearbeiten, indem Sie unten einen Kontext hinzufügen, um zu erklären, dass es funktioniert, zusammen mit Ihren Änderungen und/oder anderen Lösungen, die Ihnen geholfen haben. –

0

Wenn Sie haben die combinedReducer korrekt implementiert und mapStateToPosts sollte dann mit einer Menge von Posts aufgerufen werden, wenn sie geändert wird.

import posts from './posts_reducer'; 

combineReducers({ posts }); 

Um Beiträge in Ihrem Home Komponente machen Sie die Funktion machen ändern müssen, finden Sie rohe Umsetzung unter:

render() { 
    let postsElements = this.props.posts.map(p => { 
     return <div>p.title</div> 
    }); 
    return(
     <div> 
      <Header/> 
      <main> 
       <h1>Home</h1> 
      </main> 
      <div> 
       {postsElements} 
      </div> 
     </div> 
    ) 
} 

Sie müssen this.props.posts benutzen, um Ihre Beiträge zuzugreifen, da reagieren-redux Karten Eigenschaften vom Status zum Props-Objekt der Komponente, die die mapStateToProps-Funktion verwendet, die als erstes Argument beim Aufruf der connect-Funktion bereitgestellt wird.

Um dies zu verbessern, können Sie Ihre Blog-Komponente implementieren und div damit ersetzen.

Überprüfen Sie auch, wie es in dem von Ihnen zur Verfügung gestellten Beispiel https://github.com/jackreichert/a-wp-react-redux-theme/blob/master/src/components/main.js in dieser Datei umgesetzt wird Beiträge werden gerendert.

+0

ich meine Frage aktualisiert haben, weil ich das immer ‚This.props.posts.map() ist keine Funktion‘, wenn ich dieses aswell – coder14

+0

@ coder14 versuchen können Sie eine jsfiddle bieten, wo dieses Thema reproduziert? Sieht so aus, dass this.props.posts nicht definiert ist, wenn die Komponente gerendert wird. – Serg

0
import React, { Component } from 'react'; 
import { connect } from 'react-redux'; // glue between react and redux 
import Parser from 'html-react-parser'; 
import { LinkContainer } from 'react-router-bootstrap'; 
import { ListGroup, ListGroupItem, Image } from 'react-bootstrap'; 

class BlogPosts extends Component { 
    render() { 
    if (!this.props.posts) { 
     return (<div></div>); 
    } 
    return (
    <div className="blog-items" > 
     <ListGroup> 
      {this.renderBlogPosts()} 
     </ListGroup> 
    </div> 
    ) 
    }; 
    renderBlogPosts() { 
    if (this.props.posts.posts) { //v1 
     const posts = this.props.posts.posts; // DRY 
     return posts.map((post, index) => { 
     const excerptText = JSON.stringify(post.excerpt); 
     const excerpt = excerptText.substring(1, excerptText.length-3); 
     return (
      <LinkContainer className="blog-posts-link" key={post.ID} to={ "/blog/post/" + post.ID + '/'}> 
      { this.getHtml(
       post.ID, 
       (post.featured_image) ? post.featured_image : '', 
       post.title, 
       excerpt 
      )} 
      </LinkContainer> 
     ); 
     }); 
    }; 
    const posts = this.props.posts; // DRY 
    return posts.map((post, index) => { // v2 
     return (
     <div key={post.id}> 
      {this.getHtml(
      post.id, 
      (post._embedded['wp:featuredmedia']) 
       ? post._embedded['wp:featuredmedia'][0].media_details.sizes.thumbnail.source_url : '', 
      post.title.rendered, 
      post.excerpt.rendered 
     )} 
     </div> 
    ); 
    }); 
    }; 
    getHtml(id, imageSrc, title, excerpt) { 
    return (
     <ListGroupItem className="blog-posts-list-item"> 
     {this.getImage(imageSrc, title)} 
     <h2 className="blog-posts-title">{ Parser(title) }</h2> 
     <div className="blog-posts-excerpt">{Parser(excerpt)}</div> 
     </ListGroupItem> 
    ); 
    }; 
    getImage(imageSrc, title) { 
    return (imageSrc === "") 
     ? (<div></div>) 
     : (<div className="blog-posts-image-div"> 
      <Image className="blog-posts-image" src={imageSrc} alt={title} /> 
     </div> 
    ); 
    }; 
}; 

const mapStateToProps = (state) => ({ posts: state.posts }); 
export default connect(mapStateToProps) (BlogPosts); 
+1

Während dieser Code die Frage beantworten kann, würde die Bereitstellung eines zusätzlichen Kontextes hinsichtlich dessen, wie und/oder warum er das Problem löst, den langfristigen Wert der Antwort verbessern. Bitte lesen Sie, warum [es ist nicht klug, Code-only-Antworten zu schreiben] (https://meta.stackexchange.com/a/148274/341145) –

Verwandte Themen