0

I don't wanna use redux-form, i would like to dispatch all values of the form in the container place. The question is how to get title and content (together) by handleChange function

The container file looks like this:

import { connect } from "react-redux";
import AddPost from "../components/Posts/AddPost";
import { updateNewPost, clearNewPost } from "../actions/new-post";
import { createPost } from "../actions/posts";

const mapStateToProps = ({ title, content, auth }) => {
  return { title, content, auth };
};

const mapDispatchToProps = dispatch => {
  return {
    handleChange(event) {
      dispatch(updateNewPost(event.target.value));
    },
    handleSubmit(event, title, content, uid) {
      event.preventDefault();
      dispatch(createPost({ title, content, uid }));
      dispatch(clearNewPost());
    }
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(AddPost);

The Component file looks like this:

import React, { PropTypes } from "react";

const AddPost = ({ title, content, auth, handleChange, handleSubmit }) => (
  <form onSubmit={event => handleSubmit(event, title, content, auth.uid)}>
    <input
      type="text"
      placeholder="title"
      value={title}
      onChange={handleChange}
    />
    <input
      type="text"
      placeholder="content"
      value={content}
      onChange={handleChange}
    />
    <input type="submit" value="Post" />
  </form>
);

AddPost.propTypes = {
  title: PropTypes.string,
  content: PropTypes.string,
  auth: PropTypes.object,
  handleChange: PropTypes.func,
  handleSubmit: PropTypes.func
};

export default AddPost;

thank you for help

1
  • Welcome to Stack Overflow! Questions that ask "where do I start" are typically too broad and are not a good fit for this site. People have their own method for approaching the problem and because of this there cannot be a correct answer. Give a good read over Where to Start, then address your post. Commented May 6, 2018 at 4:12

1 Answer 1

1

You got the redux part wrong. What you want to do is setup a key in your store for each value and update it accordingly.

// store
const store = {
    title: "",
    content: ""
}

// reducer
const reducer = (state, action) => {
   switch(action.type) {
      case "UPDATE":
         return Object.assign({}, state, {[action.field]: action.payload});
      default:
        return state;
   }
}

// action creator
const updateField = (value, field) {
    return {
        type: "UPDATE",
        payload: value
        field
    };
}

// form input
<input
  type="text"
  placeholder="title"
  value={title}
  onChange={(e) => updateField(e.taget.value, "title")}
/>
<input
  type="text"
  placeholder="content"
  value={content}
  onChange={(e) => updateField(e.taget.value, "content")}
/>

Another option is to convert your stateless function into a class and manage the inputs state locally, then once you'v validated that your data is good you can dispatch a single action that will contain everything.

// form component
class Form extends React.Component {
    constructor() {
        super();

        this.state = {title: "", content: ""};

        this.validateAndSubmit = this.validateAndSubmit.bind(this);
    }

    validateAndSubmit() {
        const {title, content} = this.state;

        if (!title.length || !content.length)
            return;

        this.props.submitFormData({title, content});
    }

    render() {
        return (
          <div>
            <input
                type="text"
                placeholder="title"
                value={this.state.title}
                onChange={(e) => this.setState({title: e.target.value}, this.validateAndSubmit)}/>
            <input
                type="text"
                placeholder="content"
                value={content}
                onChange={(e) => this.setState({content: e.target.value}, this.validateAndSubmit)}/>
          </div>
        );
    }

}

// action creator
const submitFormData = (data) => {
    return {
        type: "COMPLETE",
        payload: data
    };
}

// reducer
const reducer = (state, action) => {
   switch(action.type) {
       case "COMPLETE":
           // you have your form data here...
       default:
           return state;
   }
}

This code is not tested but I hope you get the idea. Good Luck :)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.