Home > database >  split string in react and return as objects to the user
split string in react and return as objects to the user

Time:05-29

I am new to react and am trying to adjust a feature on a small web app I am building to learn the ropes. Essentially, I am trying to split up a recipe's method on /n (new line) and store each element form the array as a split up object that will be viewed by the user as a series of steps.

Eg.

Put the pasta in the water
Heat the oil
Cook the sauce

Is supposed to be split into an array based on new lines, placed into objects and returned to the user as such:

Step1
Put the pasta in the water

Step 2
Heat the oil

Step 3
Cook the sauce

I am struggling with implementing this logic - I think I am putting it at the right spot. Any guidance would be very much appreciated.

 const [methodStepsList, setMethodStepsList] = useState([])
  const [methodStepObject, setMethodStepObject] = useState({
    step_number: '',
    step_instructions: '',
  })
[...]
  const handleMethodChange = (e) => { //captures the inputted text
    let key = e.target.name
    let value = e.target.value
    console.log(`${key}:${value}`)
    let prev = { ...methodStepObject }
    prev[key] = value
    setMethodStepObject(prev)
  }

  return (
    <div>
      <div className="recipe-form-container">
        <form className="recipe-form">
         [...]
          {/* recipe method logic */}
          <div className="recipe-blurb recipe-element">
            <label>Recipe Method</label>
            <span className="method-span">
              <textarea
                rows="5"
                name="step_instructions"
                type="text"
                placeholder="Method will be split up based on new lines"
                onChange={(e) => handleMethodChange(e)}
              ></textarea>
              <button
                onClick={(e) => {
                  setMethodStepList(()
                   => [
                    e.split(/\r?\n/) //is supposed to split up the inputted text 
                  ])
                  e.preventDefault()
                }}
              >
                Add Method
              </button>
            </span>
          </div>

CodePudding user response:

  • Create a state for holding the value of the textarea: const [instructionsText, setInstructionsText] = useState("");
  • Set the value on change in textarea: <textarea ... onChange={(e) => setInstructionsText(e.target.value)} value={instructionsText} />
  • Create another state for your parsed array: const [instructionsArray, setInstructionsArray] = useState([]);
  • On your button click (it's actually a form submit) prevent the default form submission behaviour and set the array state by reading your textarea state and splitting the string by newline characters: const handleSubmit = (e) => { e.preventDefault(); setInstructionsArray(instructionsText.split(/\r?\n/)); };

Full code:

https://codesandbox.io/s/small-night-tr7e1g

Actually, you don't even need the second state, because you can directly split your string from textarea into array and render it like this:

{instructionsText.split(/\r?\n/).map((instruction, index) => {
    return <div>{`Step ${index   1}: ${instruction}`}</div>;
})}

CodePudding user response:

You can simply split the string and return the object like this:-

"Put the pasta in the water\nHeat the oil\nCook the sauce".split('\n').map((a, index) => ({[`Step ${index   1}`] : a}))

CodePudding user response:

Actually, you need only one variable to store the value of input text and control the logic to show steps based on it.

Here is an working example, whener you type into textarea and hit enter to break line, a step will show below the textarea:

import { useState } from "react";

import "./styles.css";

export default function App() {
  const [methodStepsList, setMethodStepsList] = useState([]);

  const handleMethodChange = (e) => {
    setMethodStepsList(e.target.value.split("\n"));
  };

  return (
    <div className="App">
      <div>
        <textarea
          rows="5"
          name="step_instructions"
          type="text"
          placeholder="Method will be split up based on new lines"
          onChange={(e) => handleMethodChange(e)}
        ></textarea>
      </div>
      <div>
        {methodStepsList?.map((item, idx) => (
          <>
            <div>
              <label>{`Step ${idx   1}:`}</label>
              <br />
              <span>{`${item}`}</span>
            </div>
            <br />
          </>
        ))}
      </div>
    </div>
  );
}
  • Related