Unable to send POST request by using fetch method
I am able to fetch request from the server but unable to Post the request dynamically. I am taking input value but it showing the error below:
Error: SyntaxError: "JSON.parse: unexpected character at line 1 column 1 of the JSON data"
const url = "http://some domain/api/tweets";
const input = {tweet: {body: ''}};
class App extends Component{
constructor(props){
super(props);
this.state={
error:null,
isLoaded:false,
data: [],
value: ''
}
this.onSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange(e){
this.setState({value: e.target.value});
}
componentDidMount() {
fetch("http://some domain/api/tweets")
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
data: result.data
});
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
handleSubmit(e){
e.preventDefault()
fetch(url, {
method: 'POST',
body: JSON.stringify(this.state.value),
headers:{
'Content-Type': 'application/json'
}
}).then(res => res.json())
.then(response => console.log('Success:', JSON.stringify(response)))
.catch(error => console.error('Error:', error));
}
render(){
const { error, isLoaded, data } = this.state;
if (error) {
return <div>Error: {error.message}</div>;
} else if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<div className="list-type5">
<form onSubmit={this.onSubmit} >
<input type="text" placeholder="Body" value={this.state.value} onChange={this.handleChange}/>
<input type="submit" />
</form>
<ol>
{data.map(i => (
<div key={i.id}>
<li >
<a> <b> ID:</b> {i.id} | <b> Body:</b> {i.body} | <b> Views:</b> {i.views} </a>
</li>
</div>
))}
</ol>
</div>
);
}
}
}
export default App;
Help would be appreciated.
I just changed and remove const input = {tweet: {body: ''}}; from top and write it into the handleSubmit function just check it below:-
handleSubmit(e){
e.preventDefault()
const input = {tweet: {body: this.state.value}};
fetch(url, {
method: 'POST',
body: JSON.stringify(input),
headers:{
'Content-Type': 'application/json'
}
}).then(res => res.json())
.then(response => console.log('Success:', JSON.stringify(response)))
.catch(error => console.error('Error:', error));
}
handleSubmit(e) {
fetch("http://some domain/api/tweets", { /*your object...*/ })
.then(res => res.text()) // previous .then(res => res.json())
.then(text => console.log(text))
...
}
The res.json() call seems to be wrong at this place, as your response might not be a valid JSON object. Maybe try res.text() instead and console.log your response to see what it tells you.
More infos about the response object you can find over here: MDN - Response Object
Related
sorry i'm new to React. I'm trying to make a basic social network to learn react.
Context:
When i click on the "like" button, the setState should call the function to update the state of my component, but it is updated only when i refresh the page. I think the ComponentDidUpdate function isn't called like it should. What did i do wrong? Thanks for your help!
Here are the parts of the code :
Like button component:
class Like_Button extends React.Component {
constructor(props) {
super(props);
this.state = {liked : "Like"};
}
isliked(){
fetch("likes_of_user/")
.then(res => res.json())
.then((result) => {
result.map(x => {if(this.props.pk == x.liked_post){this.setState({liked: "Unlike"});}});
})
}
componentDidMount() {
this.isliked();
}
componentDidUpdate(prevProps, prevState) {
if (prevState.liked !== this.state.liked) {
this.isliked();
}
}
render() {
return (
<button className = "buttons" onClick={() => {
var csrftoken = getCookie('csrftoken');
fetch(`like_post/${this.props.pk}`, {method: "POST", headers: {'Accept': 'application/json', 'Content-Type': 'application/json','X-CSRFToken': csrftoken}})
}}>{this.state.liked}</button>
)
}
}
Newsfeed component:
class Newsfeed_comp extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
isLoaded: false,
items: []
};
}
componentDidMount() {
fetch("get_newsfeed/")
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
items: result
});
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
render() {
const { error, isLoaded, items } = this.state;
if (error) {
return <div>Error: {error.message}</div>;
} else if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<ul>
{items.map((item ,index) => (
<li className="postbox" key={`${item}${index}`}>
{item.author}
{item.date}
{item.content}
<Like_Button pk={item.id} />
</li>
))}
</ul>
);
}
}
}
ReactDom render:
ReactDOM.render(<Newsfeed_comp />, document.getElementById("newsfeed_view"))
Try something like this:
LikeButton.js
import React, { useEffect, useState } from 'react';
export default function LikeButton({ pk }) {
const [like, setLike] = useState(false);
useEffect(() => {
const fetchLike = async () => {
const res = await fetch("likes_of_user/");
const result = await res.json();
if (result.length > 0) {
setLike(result.find(item => item.liked_post === pk));
}
};
try {
fetchLike();
} catch (error) {
// handle error
}
});
const handleClick = async () => {
const csrftoken = getCookie('csrftoken');
return fetch(`like_post/${pk}`, {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken
},
method: 'POST',
});
};
return (
<button className='buttons' onClick={handleClick}>
{like}
</button>
);
};
NewsFeed.js
import React, { useEffect, useState } from 'react';
export function NewsFeed() {
const [error, setError] = useState(null);
const [isLoaded, setIsLoaded] = useState(false);
const [items, setItems] = useState([]);
useEffect(() => {
const getNewsFeed = async () => {
const res = await fetch('get_newsfeed/');
const result = await res.json();
setIsLoaded(true);
setItems(result);
};
try {
getNewsFeed();
} catch (error) {
setIsLoaded(true);
setError(error);
}
});
if (error) return <div>Error: {error.message}</div>;
if (isLoaded) return <div>Loading...</div>;
const list = items.map((item) => (
<li className='postbox' key={item.content}>
{item.author}
{item.date}
{item.content}
<LikeButton pk={item.id} />
</li>
));
return <ul>{list}</ul>;
};
App.js
ReactDOM.render(<NewsFeed />, document.getElementById('newsfeed_view'));
Looks like you've reversed your logic, i.e. your button directly updates the data in the backend but does nothing to update component state, so the componentDidUpdate isn't called as you've seen. The refresh is required so the component is remounted and the componentDidMount can fetch the likes data.
Try instead to update local state first, then use componentDidUpdate to issue the side-effect of updating the backend.
constructor(props) {
super(props);
this.state = { liked: true };
}
isliked() {
fetch("likes_of_user/")
.then(res => res.json())
.then((result) => {
result.map(x => {
if (this.props.pk === x.liked_post) {
this.setState({ liked: false });
}
});
})
}
componentDidUpdate(prevProps, prevState) {
if (prevState.liked !== this.state.liked) {
const csrftoken = getCookie('csrftoken');
fetch(
`like_post/${this.props.pk}`,
{
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken,
},
}
);
}
}
<button
className="buttons"
onClick={() => this.setState(
prevState => ({ liked: !prevState.liked })
)}
>
{this.state.liked ? "Liked" : "Unliked"}
</button>
I'm trying to build a todo page where I can input todos in my input field. All todos will be rendered below. I managed to build a form where I can type in a todo title and send it to my database. A small problem I'm having here is that I need to refresh the page after pushing the add button to see the new list. I assume this is because I use componentDidMount and this updates only at page refresh. Any idea how I can do this at page refresh (componentDidUpdate) AND at state change ?
FRONT-END
import React from 'react'
import './Todo.css'
import Todoitem from '../components/Todoitem'
import axios from 'axios'
import qs from "qs"
import DefaultLayout from "../layout/Default"
class Todo extends React.Component {
constructor() {
super()
this.state = {
title:"",
todos:[]
}
this.handleChange=this.handleChange.bind(this)
this.handleSubmit=this.handleSubmit.bind(this)
}
componentDidMount(){
axios({
method: "GET",
url: `${process.env.REACT_APP_API_BASE}/todo`,
withCredentials: true
})
.then(response => {
console.log(response)
let todolist = response.data;
this.setState({todos:todolist})
})
.catch(error => {
console.log("You've made an error when getting the todos charles: ",error)
})
}
handleChange(event){
event.preventDefault()
let name = event.target.name
let value = event.target.value
this.setState({
[name]:value
})
console.log(this.state.title)
}
handleSubmit(event){
event.preventDefault()
if (!this.state.title) {
debugger
}
axios({
method: "POST",
url: `${process.env.REACT_APP_API_BASE}/todo`,
data: qs.stringify({title: this.state.title}),
headers: {"content-type": "application/x-www-form-urlencoded"},
withCredentials: true
})
.then((response) => {
console.log(response)
})
.catch((error) => {
console.log(error.response)
})
}
handleDelete(todoId){
axios
.delete(`${process.env.REACT_APP_API_BASE}/todo/${todoId}`)
.then(response => {
const remainingTodos = this.state.todos.filter(element => element._id !== todoId)
this.setState({
todos: remainingTodos
})
})
.catch(err => console.log(err))
}
render() {
return (
<div>
<DefaultLayout>
<h1>To-do things for this app</h1>
<h2 className="todotitle">Add your to-do here, Charles!</h2>
<form className="todocontainer" onClick={this.handleSubmit}>
<div className="inputbuttonandfield">
<div className="inputcontainer">
<div className="captionpart">
<label className="captionlabel" htmlFor="title">Add to-do:</label><br></br>
<input className="captionform" type="text" name="title" value={this.state.title} placeholder="Type your to-do here!" onChange={(e) => this.handleChange(e)}></input>
<button className="shootbutton">Add!</button>
</div>
</div>
</div>
</form>
{
this.state.todos.map(element=> (
<div className="todosoverviewlister" key={element._id}>
<Todoitem id={element._id} title={element.title} />
<button className="tododelete" onClick={()=> this.handleDelete(element._id)}>Delete</button>
</div>
))
}
</DefaultLayout>
</div>
)
}
}
export default Todo
Todomodel
const mongoose = require("mongoose")
const Schema = mongoose.Schema
const todoSchema = new Schema({
title: String
})
const Todo = mongoose.model("todos",todoSchema)
module.exports = Todo
BACKEND
//request todos
router.get("/todo", (req,res) => {
Todo
.find()
.then(response => {
res.json(response)
})
.catch(error => {
res.json(error)
})
})
//delete todo
router.delete("/todo/:id", (req,res)=>{
Todo
.findByIdAndDelete(req.params.id)
.then(response => {
res.json(response)
})
.catch(error => {
res.json(error)
})
})
You can either update the state or sync up with database by sending another GET. Let me break it down into 2 solutions:
Just update the state
Make a GET request after the POST request and update the state
Just update the state
// you code ...
handleSubmit(event){
event.preventDefault()
const newTodo = { title: this.state.title }; // extract your todo into const
axios({
method: "POST",
url: `${process.env.REACT_APP_API_BASE}/todo`,
data: qs.stringify(newTodo), // send todo in the POST
headers: {"content-type": "application/x-www-form-urlencoded"},
withCredentials: true
})
.then((response) => {
console.log(response)
this.setState(prevState => ({ // immutably update the state
todos: [...prevState.todos, newTodo]
}));
})
.catch((error) => {
console.log(error.response)
})
}
// your code ...
Send GET after POST:
// your Todo component
class Todo extends React.Component {
constructor() {
super();
this.state = {
title: "",
todos: [],
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
// extract method for loading TODOs (your previous componentDidMount)
loadTodos = () => {
axios({
method: "GET",
url: `${process.env.REACT_APP_API_BASE}/todo`,
withCredentials: true,
})
.then((response) => {
console.log(response);
let todolist = response.data;
this.setState({ todos: todolist });
})
.catch((error) => {
console.log(
"You've made an error when getting the todos charles: ",
error
);
});
}
componentDidMount() {
this.loadTodos(); // use the extracted method
}
handleChange(event) {
event.preventDefault();
let name = event.target.name;
let value = event.target.value;
this.setState({
[name]: value,
});
console.log(this.state.title);
}
handleSubmit(event) {
event.preventDefault();
if (!this.state.title) {
debugger;
}
axios({
method: "POST",
url: `${process.env.REACT_APP_API_BASE}/todo`,
data: qs.stringify({ title: this.state.title }),
headers: { "content-type": "application/x-www-form-urlencoded" },
withCredentials: true,
})
.then((response) => {
console.log(response);
this.loadTodos(); // use the extracted method
})
.catch((error) => {
console.log(error.response);
});
}
handleDelete(todoId) {
axios
.delete(`${process.env.REACT_APP_API_BASE}/todo/${todoId}`)
.then((response) => {
const remainingTodos = this.state.todos.filter(
(element) => element._id !== todoId
);
this.setState({
todos: remainingTodos,
});
})
.catch((err) => console.log(err));
}
render() {
return (
<div>
<DefaultLayout>
<h1>To-do things for this app</h1>
<h2 className="todotitle">Add your to-do here, Charles!</h2>
<form className="todocontainer" onClick={this.handleSubmit}>
<div className="inputbuttonandfield">
<div className="inputcontainer">
<div className="captionpart">
<label className="captionlabel" htmlFor="title">
Add to-do:
</label>
<br></br>
<input
className="captionform"
type="text"
name="title"
value={this.state.title}
placeholder="Type your to-do here!"
onChange={(e) => this.handleChange(e)}
></input>
<button className="shootbutton">Add!</button>
</div>
</div>
</div>
</form>
{this.state.todos.map((element) => (
<div className="todosoverviewlister" key={element._id}>
<Todoitem id={element._id} title={element.title} />
<button
className="tododelete"
onClick={() => this.handleDelete(element._id)}
>
Delete
</button>
</div>
))}
</DefaultLayout>
</div>
);
}
}
export default Todo;
I believe the issue is that you're not updating the state when you submit (during the add operation). In your delete, you correctly keep the list in state synced with the list on the server by removing the element locally as well. In the add, you should to something similar by adding the new element to the list in state (or more precisely, make a deep copy and overwrite the one in state). That should do it.
There is no need to refetch the entire list from the server unless there are multiple users operating on the same list. If that's the case, you can add a get() call in the response of your submit. As long as the response of that operation writes to state, it will update correctly. But again, avoid that unless you need it as it will make your app slower and less responsive.
I am fairly new to react JS and I've implemented 2 dropdown boxes whose options are displayed by hitting an API. I want to obtain the selected value but I am getting the following error:
TypeError: Cannot read property 'value' of undefined.
As of now I just tried to obtain the value from one dropdown.
This is my code,
import React from 'react';
import Select from 'react-select';
import './Search.css';
class SearchForm extends React.Component {
constructor(props){
super(props);
this.state={
filtered :[],
values1 :[],
values2 :[],
selectedCategory:''
}
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
try{
this.setState({selectedCategory: event.target.value});
} catch (err) {
console.error('err', err);}}
componentDidMount() {
this.fetchData1()
this.fetchData2()
}
fetchData1 = async () => {
await fetch('/category/all')
.then(res => res.json())
.then(res =>
this.setState({
values1: res,
}),
)
.catch(error => console.log(error))
}
fetchData2 = async () => {
await fetch('/loc/all')
.then(res => res.json())
.then(res =>
this.setState({
values2: res,
}),
)
.catch(error => console.log(error))
}
async handleSubmit(event){
event.preventDefault();
try{
const url ='/jobs/all/'
const Response = await fetch((url),{
method: `GET`,
mode: 'cors',
headers: {
'Accept': 'application/json'
}});
const filtered = [];
const res = await Response.json();
const Location = this.menu2.value
const Category = this.menu1.value
console.log(Location)
console.log(Category)
Object.keys( res ).forEach( function( key ) {
if( res[key].location === Location && res[key].category === Category ) {
filtered[key] = res[key];}
});
this.setState({filtered})
console.log(this.state.filtered)
}
catch (err) {
console.error('err', err);}
};
render() {
let option1 = []
if (this.state.values1) {
this.state.values1.forEach(eachCategory => {
let Category = {}
Category.value = eachCategory.id
Category.label = eachCategory.category
option1.push(Category)
})
}
console.log(option1)
let option2 = []
if (this.state.values2) {
this.state.values2.forEach(eachLocation => {
let Location = {}
Location.value = eachLocation.id
Location.label = eachLocation.location
option2.push(Location)
})
}
console.log(option2)
return (
<div>
<form action="/search" onSubmit={this.handleSubmit.bind(this)}>
<Select options={option1} value={this.state.selectedCategory} placeholder='Category' onChange={this.handleChange}>
</Select>
<Select options={option2} placeholder='Location'/>
<button>Find</button>
</form>
{this.state.filtered.map((data)=>{
// return <div>{data.location}</div> // you can render here list items
return (
<div className="flex-container">
<div key={data.id}>
<div>Job Title: {data.category}</div>
<div>Location: {data.location}</div>
<div>Position: {data.position}</div>
<div>Duration: {data.duration}</div>
<div>Skills Required: {data.skills_req}</div>
<div>Apply By: {data.apply_by}</div>
<div>Starting Date: {data.starting_date}</div>
<div>Stipend: {data.stipend}</div>
<div>About Work: {data.about_work}</div>
<div>Perks: {data.perks}</div>
</div>
</div>)
})}
</div>
);
}
}
export default SearchForm;
Please point out where am I wrong.
Well, according to the react-select documentation you're handling onChange in a wrong way. It should just be like this.
handleChange = selectedOption => {
this.setState({ selectedOption });
console.log(`Option selected:`, selectedOption);
};
https://www.npmjs.com/package/react-select
So in your case, you just have to change this.setState({selectedCategory: event.target.value}); to this.setState({selectedCategory: event}); :
handleChange(event) { //give it a proper name, say selectedValue instead ofevent'
try{
this.setState({selectedCategory: event}); //no need of event.target.vaue; in fact that will be undefined
} catch (err) {
console.error('err', err);}}
Please note that this Select is different from normal select where you get the value using e.target.value in the handleChange method. The Select comes in with react-select package and hence you need to follow the usage accordingly.
You didn't send event to handleChange method.
Try:
onChange={e => this.handleChange(e)}
I'm working with react, redux-form and laravel.
I have created a form to be able to insert notes in the database but when I show the Request in laravel an empty array always appears.
I do not know what I'm doing wrong.
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
notes: [],
};
this.submitToServer = this.submitToServer.bind(this)
this.submit = this.submit.bind(this)
}
componentWillMount() {
fetch('http://127.0.0.1:8000/notes')
.then(res => res.json())
.then(json => json.results)
.then(notes => this.setState({ notes }))
.catch(console.log)
}
async submitToServer(data) {
let response = await fetch('http://127.0.0.1:8000/notes', {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-type': 'application/json',
},
body: JSON.stringify(data)
})
let responseJSON = await response.json()
return responseJSON
}
submit({ title, content }) {
this.submitToServer({ title, content })
.then(res => this.setState(prevState => ({
notes: [...prevState.notes, {
id: prevState.notes.pop().id + 1,
title: title,
content: content
}]
})))
}
render() {
if (this.state.notes.length > 0) {
return (
<div>
<h1>Notas</h1>
<Paper>
<form onSubmit={this.props.handleSubmit(this.submit)}>
<Field name="title" label="Title" component={renderField} type="text" />
<Field name="content" label='Content' component={renderField} type="text" />
<button type="submit">Submit</button>
</form>
</Paper>
))}
</div>
)
} else {
return <p>Cargando notas...</p>
}
}
}
In laravel at the moment I'm just returning the Request to show what it contains.
public function storeNote(Request $request) {
return $request;
}
I'm trying to output an article on a new page, but the article on the new page does not appear in the console it's not there, it's empty, how can I fix it.
backend - Ruby on Rails
frontend - React/Redux
The page that displays the article.
task_details.js
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import Exit from '../authentication/exit';
import { browserHistory } from 'react-router';
import { getTask } from '../../actions/tasks';
import TasksList from './tasks_list';
import Link from 'react-router'
class TaskDetails extends Component {
componentDidMount () {
let id = this.props.params.id;
this.props.onGetTask(id);
};
render() {
const { task } = this.props
console.log(this.props.location.pathname, "xxxxxxxx")
return (
<div>
{ this.props.task ?
<div className="container">
<h2 className="text-center">{task.title}</h2>
<div className="col-md-2">
<h4 className="pull-right"><i>{task.due_date}</i></h4>
</div>
<div className="clearfix"></div>
<div className="description">
<p>{task.description}</p>
</div>
</div>
:
<div className="container">
<div><h2>Not found</h2></div>
</div>
}
</div>
);
}
};
export default connect(
state => ({
task: state.tasks.item
}),
dispatch => ({
onGetTask: (id) => {
dispatch(getTask(id));
},
})
)(TaskDetails);
The page responsible for the task.
tasks.js
import axios from 'axios';
import cookie from 'react-cookies';
//const API_URL = `https://evening-taiga-79121.herokuapp.com/todos`;
const API_URL = `http://localhost:3000/todos`;
let headers = { 'Content-Type': 'application/json', };
const token = cookie.load('token');
export function fetchTasks(user_id){
return function(dispatch, getState) {
let body = JSON.stringify({ token: token });
headers['Authorization'] = `Bearer ${token}`;
axios.get(`${API_URL}`, { headers, body })
.then(res => {
if (res.status === 200) {
dispatch({ type: 'GET_TASKS', payload: res.data });
}
})
.catch(e => {
console.error("error: ", e);
})
}
}
export function getTask(id) {
return function(dispatch, getState) {
return new Promise((resolve, reject) => {
axios.get(`${API_URL}/${id}`, { headers: headers })
.then(res => {
resolve(res)
dispatch({ type: 'GET_TASK_ID', payload: res.data });
})
.catch(e => {
console.error("error: ", e);
reject(e)
})
})
}
}
export function deleteTask(id){
return function(dispatch, getState) {
let body = { token: token };
axios.delete(`${API_URL}/${id}`, { params: body, headers: headers })
.then(res => {
dispatch({ type: 'DELETE_TASK', payload: id });
})
.catch(id => {
console.error("error", id);
})
}
}
export function addTask(task){
return function(dispatch, getState) {
let body = JSON.stringify({todo: task, token: token});
console.log(body);
axios.post(API_URL, body, { headers: headers })
.then(res => {
dispatch({ type: 'ADD_TASK', payload: res.data });
})
.catch(e => {
console.error(e);
})
}
}
export function completedTask(id, complete){
return function(dispatch, getState) {
if (complete === true) {
complete = false
} else {
complete = true
}
let task = {id: id, completed: complete};
let body = {todo: task, token: token};
axios.patch(`${API_URL}/${task.id}`, body, { headers: headers })
.then(res => {
dispatch({ type: 'COMPLITED_TASK', payload: res.data });
})
.catch(e => {
console.error("error: ", e);
})
}
}
export function sortTasks(sortBy){
return function(dispatch, getState) {
let body = JSON.stringify({ token: token, sortByTitle: sortBy.title, sortByAsc: sortBy.asc });
axios.post(`${API_URL}/sort`, body, { headers: headers })
.then(res => {
console.log(res);
if (res.status === 200) {
dispatch({ type: 'SORT_BY', payload: sortBy });
dispatch({ type: 'FETCH_TODOS_SUCCESS', payload: res.data });
}
})
.catch(e => {
console.error("error: ", e);
})
}
}
export function editTask(task){
return function(dispatch, getState) {
let body = JSON.stringify({todo: task, token: token});
axios.patch(`${API_URL}/${task.id}`, body, { headers: headers })
.then(res => {
dispatch({ type: 'EDIT_TASK', payload: res.data });
})
.catch(e => {
console.error("error: ", e);
})
}
}
The page with which we go to the page with the article.
tasks_index.js
import React, {Component} from 'react';
import { Router, Route, hashHistory } from 'react-router';
import Exit from '../authentication/exit';
import TasksList from './tasks_list';
import New from './new';
import Edit from './edit';
import {connect} from 'react-redux';
import { Link } from 'react-router';
import {fetchTasks, sortTasks} from '../../actions/tasks';
const Tasks_Index = ({user_id, onFetchTasks}) => {
if (user_id) {
onFetchTasks(user_id)
return (
<div>
<div className="container">
<div className="row">
<div className="navbar-header col-md-2">
<a href="#">
<h2 className="pull-right">TASKS</h2>
</a>
</div>
<ul>
<div className="pull-right nav navbar-nav">
<h4><li className=""><Link to="/user/exit">Log out</Link></li></h4>
</div>
</ul>
</div>
</div>
<div className="container">
<div className="row">
<New />
<Edit />
<TasksList />
</div>
</div>
</div>
);
} else
return null;
}
export default connect(
state => ({
user_id: state.user.id,
editId: state.tasks.edit,
sortBy: state.tasks.sortBy
}),
dispatch => ({
onFetchTasks: (user_id) => {
dispatch(fetchTasks(user_id));
}
})
)(Tasks_Index);
Thanks for the help.