skip to Main Content

When I run my React code I get makeStory is not a function.

Here is the parent component called Madlib

import React, { useState } from "react";
import UserForm from "./UserForm";
import Story from "./Story";
import { v4 as uuid } from "uuid/dist";

const Madlib = () => {
  const [story, setStory] = useState([]);
  const [showStory, setShowStory] = useState(false);

  const makeStory = (newStory) => {
    setStory((story) => [...story], { ...newStory, id: uuid() });
  };

  return (
    <div className="Madlib">
      <h1>Madlibs</h1>
      {showStory ? (
        <Story story={story[0]} />
      ) : (
        <UserForm setShowStory={setShowStory} makeStory={makeStory} />
      )}
    </div>
  );
};

export default Madlib;

Here is the child component called UserForm

import React, { useState } from "react";
import "./UserForm.css";

const UserForm = ({ setShowStory, makeStory }) => {
  const initialState = {
    noun: "",
    noun2: "",
    adjective: "",
    color: "",
  };
  const [formData, setFormData] = useState(initialState);

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData((formData) => ({
      ...formData,
      [name]: value,
    }));
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    makeStory({ ...formData });
    setShowStory(true);
    setFormData(initialState);
  };

  return (
    <div className="UserForm">
      <form onSubmit={handleSubmit}>
        <input
          id="noun"
          type="text"
          name="noun"
          placeholder="noun"
          value={formData.noun}
          onChange={handleChange}
        />
        <input
          id="noun2"
          type="text"
          name="noun2"
          placeholder="noun2"
          value={formData.noun2}
          onChange={handleChange}
        />
        <input
          is="adjective"
          type="text"
          name="adjective"
          placeholder="adjective"
          value={formData.adjective}
          onChange={handleChange}
        />
        <input
          id="color"
          type="text"
          name="color"
          placeholder="color"
          value={formData.color}
          onChange={handleChange}
        />

        <button className="button">Get Story</button>
      </form>
    </div>
  );
};

export default UserForm;

I am passing the function, makeStory, from Madlibs to UserForm but I can’t figure out why I’m still getting the error the makeStory is not a function. I have destructured props in the child component to have setShowStory, makeStory.

2

Answers


  1. You have an extra set of parentheses around the spread operator.

    It should be:

    const makeStory = (newStory) => {
      setStory((story) => [...story, { ...newStory, id: uuid() }]);
    };
    

    Remove the extra parentheses around [...story, { ...newStory, id: uuid() }] to correctly update the story state with the new story object.

    Login or Signup to reply.
  2. You should spread the stories array (the current state) and then add the new story object to it. This way, you maintain the previous stories and add a new one to the array.

    const makeStory = (newStory) => {
      setStory((stories) => [...stories, { ...newStory, id: uuid() }]);
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search