Javascript 使用Redux从表单发布数据

Javascript 使用Redux从表单发布数据,javascript,reactjs,redux,Javascript,Reactjs,Redux,另一个新手问题。我想用我的表格发一篇帖子。我的Post.js如下所示: import React, { Component } from 'react'; import PropTypes from 'prop-types'; import PostForm from './PostFormContainer'; export class Post extends Component { static propTypes = { posts: PropTypes.any,

另一个新手问题。我想用我的表格发一篇帖子。我的Post.js如下所示:

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;
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;
和PostContainer.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);
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);
我的减速机呢

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;
  }
}
现在我的console.logs显示我的所有数据都是未定义的。不确定我错过了什么,但我无法解决这个问题

这也是我的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;


您的
PostForm
元素使用props
title
body
,但您使用
PostForm
的位置不会向其发送
body
title
prop

我不知道您的特定用例,但在React/Redux中,有两种方法可以将属性发送到元素:

<PostForm body={this.state.postFormBody} title={this.state.postFormTitle} />


或者通过使用Redux连接器、mapStateToProps函数,并返回一个带有“body”和“title”键的对象,这些键与Redux存储中的内容相匹配

您的PostForm元素接受
body
作为道具,但您似乎没有向其发送
body
道具……这只是我的意见,我不知道您的整个用例,但是,您将表单内容绑定到Redux状态有什么好的理由吗?应用程序的任何其他部分是否需要知道或永久存储用户在表单文本输入中键入的信息?因为在我看来,大多数React表单输入都应该用DefaultValue属性填充,并且您应该向api提交
FormData
,而不是试图用state或redux控制所有内容。没有特殊情况。我只是在尝试不同的东西,很公平。如果要在组件中使用
this.props.body
来决定请求中发送的内容,则需要在某个位置设置
body
prop,无论是在使用组件的位置,还是在Redux连接器的某个位置。谢谢:)我会试试的