Ive decided to tryout React with GraphQL, Apollo, and Wordpress.
Repo: https://github.com/teaglebuilt/teaglebuilt.com
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { ApolloClient } from 'apollo-boost';
import { createHttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { BrowserRouter } from 'react-router-dom';
import { ApolloProvider } from 'react-apollo';
import Config from './config';
const client = new ApolloClient({
link: createHttpLink({
uri: Config.gqlUrl,
}),
cache: new InMemoryCache(),
});
ReactDOM.render(
<BrowserRouter>
<ApolloProvider client={client}>
<App />
</ApolloProvider>
</BrowserRouter>,
document.getElementById('root')
);
App.js
import React from 'react';
import { Switch, Route } from 'react-router-dom';
import Home from './components/Home';
import Header from './components/Header';
import Sidebar from './components/Sidebar';
import Page from './components/Page';
import Post from './components/Post';
import Category from './components/Category';
import Tagbar from './components/Tagbar';
import Tag from './components/Tag';
import './styles/index.css';
export default () => (
<div className="">
<Header />
<div className="container w-full flex flex-wrap mx-auto px-2 pt-8 lg:pt-16 mt-16">
<Sidebar />
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/page/:slug" component={Page} />
<Route exact path="/post/:slug" component={Post} />
<Route exact path="/category/:slug" component={Category} />
<Route exact path="/tag/:id" component={Tag} />
</Switch>
<Tagbar />
</div>
</div>
);
Tagbar.js
import React, { Component } from 'react';
import { withApollo } from 'react-apollo';
import { Link } from 'react-router-dom';
import gql from 'graphql-tag';
const TAGS_QUERY = gql`
query {
tags {
edges {
node {
id
link
name
slug
posts {
edges {
node {
id
}
}
}
}
}
}
}
`;
class Tagbar extends Component {
constructor(props){
super(props);
this.state = {
tags: []
}
}
componentDidMount(){
this.executeTagsQuery();
}
executeTagsQuery = async () => {
const { client } = this.props;
const result = await client.query({
query: TAGS_QUERY
})
let tags = result.data.tags.edges;
this.setState({
tags: tags
})
}
render(){
const { tags } = this.state;
return(
<div className="w-full lg:w-1/5 lg:px-6 text-xl text-gray-800 leading-normal">
<h1>TagBar</h1>
<ul>
{tags.map(tag => (
<li key={tag.node.slug}>
<Link to={`/tag/${tag.node.id}`}>
{tag.node.name}
</Link>
</li>
))}
</ul>
</div>
)
}
}
export default withApollo(Tagbar);
So you see here in the graphql query that i could pass the posts for each tag in the map function to the tag component but im not sure if i should do that...meaning render the tag component inside of tagbar.js...
tagbar is a sidebar on the right side of the ui with the list of tags.
tag.js
import React, { Component } from 'react';
import { withApollo } from 'react-apollo';
import { Link } from 'react-router-dom';
import gql from 'graphql-tag';
const TAG_QUERY = gql`
query TagQuery($filter: ID!) {
tag(id: $filter) {
slug
name
posts {
edges {
node {
content
slug
title
}
}
}
}
}
`;
class Tag extends Component {
constructor(props){
super(props);
this.state = {
tag: {
name: "",
posts: []
}
}
}
componentDidMount(){
this.executeTagQuery();
}
executeTagQuery = async () => {
const { match, client } = this.props;
const filter = match.params.id;
const result = await client.query({
query: TAG_QUERY,
variables: { filter }
})
const { name } = result.data.tag;
let posts = result.data.tag.posts.edges;
posts = posts.map(post => {
const finalLink = `/tag/${post.node.id}`;
const modifiedTag = { ...post };
modifiedTag.node.link = finalLink;
return modifiedTag;
})
const tag = {
name,
posts
}
this.setState({ tag });
}
render(){
const { tag } = this.state;
return (
<div className="w-full lg:w-3/5 p-8 mt-6 lg:mt-0 text-gray-900 leading-normal bg-white border border-gray-400 border-rounded">
<h4><strong>Posts with Tag:</strong> <em>{tag.name}</em></h4>
<ul className="py-10 mx-auto">
{tag.posts.map(post=> (
<li key={post.node.slug} className="">
<div className="flex my-10">
<div className="bg-white w-3/4 m-auto border-1 border-dashed border-gray-100 shadow-md rounded-lg overflow-hidden">
<img src="https://via.placeholder.com/400x200" alt="" className="w-full object-cover object-center" />
<div className="p-4">
<Link to={post.node.link} className="mx-auto f text-gray-900 font-semibold">{post.node.title}</Link>
<br/>
<span className="text-gray-700">{post.node.content}</span>
</div>
</div>
</div>
</li>
))}
</ul>
</div>
)
}
}
export default withApollo(Tag);
Top comments (3)
Hey, community mod here. I highly suggest you use the #help tag to get more traction on this. Cheers!
haha thats great advice, thank you. I did not realize I left the most relevant tag out!
haha no worries!