Another newbie propblem. I want to post a post with my form. I have Post.js that looks like this:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import PostForm from './PostFormContainer';
export class Post extends Component {
static propTypes = {
posts: PropTypes.any,
fetchPosts: PropTypes.func,
sendPostData: PropTypes.func,
};
componentDidMount() {
const { fetchPosts } = this.props;
fetchPosts();
}
// onSubmit = (e, id, title, body) => {
// e.preventDefault();
// axios
// .post('https://jsonplaceholder.typicode.com/posts', {
// id,
// title,
// body,
// })
// .then(res =>
// this.setState({
// posts: [...this.state.posts, res.data],
// })
// );
// };
// onSubmit(e, id, title, body) {
// e.preventDefault();
// console.log('data');
// console.log('data', id);
// console.log('data', title);
// console.log('data', body);
// this.props.sendPostData(id, title, body);
// console.log('sendPostData', this.props.sendPostData(id, title, body));
// }
render() {
console.log('props', this.props);
const { posts } = this.props;
if (!posts.length) {
return (
<div>
<PostForm addPost={this.onSubmit} />
</div>
);
} else {
return (
<div>
<PostForm addPost={this.onSubmit} />
<br />
<div>
{posts.map(post => (
<div key={post.id}>
<h3>{post.title}</h3>
<p>{post.body}</p>
</div>
))}
;
</div>
</div>
);
}
}
}
export default Post;
Where I have <PostForm addPost={this.onSubmit} />
My PostForm.js looks like this:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class PostForm extends Component {
///state = {
// title: '',
// body: '',
//};
static propTypes = {
posts: PropTypes.any,
// fetchPosts: PropTypes.func,
sendPostData: PropTypes.func,
};
//onChange = e => {
//this.setState({
// e.target.name zawsze będzie targetował pole z value i zmieniał jego stan
// [e.target.name]: e.target.value,
// });
//};
// onSubmit(e, id, title, body) {
// e.preventDefault();
// console.log('data');
// console.log('data', id);
// console.log('data', title);
// console.log('data', body);
// }
onSubmit(e, id, title, body) {
e.preventDefault();
console.log('data');
console.log('data', id);
console.log('data', title);
console.log('data', body);
// const post = {
// title,
// body,
// };
this.props.sendPostData(title, body);
// console.log('sendPostData', this.props.sendPostData(post));
}
render() {
console.log('props form', this.props);
const { title, body } = this.props;
return (
<div>
<h1> Add Post </h1>
<form onSubmit={e => this.onSubmit(e, title, body)}>
<div>
<label>Title: </label>
<input
type='text'
name='title'
value={title}
onChange={this.onChange}
/>
</div>
<div>
<label>Body: </label>
<textarea name='body' value={body} onChange={this.onChange} />
</div>
<button type='submit'>Submit</button>
</form>
</div>
);
}
}
export default PostForm;
Here I want to send this with my action. I have two container files PostFormContainer.js
import { connect } from 'react-redux';
import PostForm from './PostForm';
import { sendPost } from '../reducers/postReducers';
const mapStateToProps = state => ({
posts: state.posts,
});
const mapDispatchToProps = dispatch => ({
sendPostData: post => dispatch(sendPost(post)),
});
export default connect(mapStateToProps, mapDispatchToProps)(PostForm);
and PostContainer.js
import { connect } from 'react-redux';
import Post from './Post';
import { fetchFromApi } from '../reducers/postReducers';
const mapStateToProps = state => ({
posts: state.posts,
});
const mapDispatchToProps = dispatch => ({
fetchPosts: () => dispatch(fetchFromApi()),
// sendPostData: (id, title, body) => dispatch(sendPost({ id, title, body })),
});
export default connect(mapStateToProps, mapDispatchToProps)(Post);
and my reducer
import Axios from 'axios';
const reducerName = 'posts';
const createActionName = name => `/${reducerName}/${name}`;
/* action type */
const FETCH_POSTS = createActionName('FETCH_POSTS');
const SUBMIT_POST = createActionName('SUBMIT_POST');
/* action creator */
export const fetchStarted = payload => ({ payload, type: FETCH_POSTS });
export const submitPost = payload => ({ payload, type: SUBMIT_POST });
/* thunk */
export const fetchFromApi = () => {
return (dispatch, getState) => {
Axios.get('https://jsonplaceholder.typicode.com/posts?_limit=5').then(
res => dispatch(fetchStarted(res.data))
// console.log('res', res)
// console.log('res data', res.data)
);
};
};
export const sendPost = (postId, postTitle, postBody) => {
return (dispatch, getState) => {
Axios.post('https://jsonplaceholder.typicode.com/posts', {
id: postId,
title: postTitle,
body: postBody,
}).then(res => {
dispatch(submitPost(res.data));
});
};
};
/* reducer */
export default function reducer(state = [], action = {}) {
switch (action.type) {
case FETCH_POSTS:
return action.payload;
case SUBMIT_POST: {
return {
...state,
data: action.payload,
};
}
default:
return state;
}
}
Right now my console.logs shows that all my data is undefined. Not sure what the I am missing, but I can't solve this.
Here is also my stro.js
import { combineReducers, applyMiddleware, createStore } from 'redux';
import thunk from 'redux-thunk';
import { composeWithDevTools } from 'redux-devtools-extension';
import postReducer from './reducers/postReducers';
const initialState = {
posts: {
data: {},
},
};
const reducers = {
posts: postReducer,
};
Object.keys(initialState).forEach(item => {
if (typeof reducers[item] == 'undefined') {
reducers[item] = (state = null) => state;
}
});
const combinedReducers = combineReducers(reducers);
const store = createStore(
combinedReducers,
initialState,
composeWithDevTools(applyMiddleware(thunk))
);
export default store;
Your PostForm
element uses props title
and body
, but the place where you use PostForm
doesn't send it a body
or title
prop.
I don't know your particular use case, but in React/Redux there are two ways to send a property to an element:
<PostForm body={this.state.postFormBody} title={this.state.postFormTitle} />
Or by using your Redux connector, mapStateToProps function, and returning an object with 'body' and 'title' keys that match something in your Redux store
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.