How can I render user's input (which is stored in an array) with LINE BREAKS using react.js?

Issue

I’ve been trying to render {ingredients} with line breaks, each time the user presses Enter and keys in another ingredient. I’ve been getting all the user’s inputs in one line e.g. grapeonionlettuce I’m not sure what, where or how to add code so that it’ll have line breaks – tried using CSS too, by referencing the className return-ingredients-list and using white-space etc. but to no avail. Please help, thanks in advance, if possible.

//import { useState} from "react";
//import {Paper} from "@material-ui/core";
const {useState} = React;

const CRBUploadRecipe = () => {
    const [recipeName, setRecipeName] = useState("");
    const [selectedFile, setSelectedFile] = useState(undefined);
    const [ingredients, setIngredients] = useState([]);

    const handleEnterKeyPress = (e) => {
        if(e.which === 13) {
            const input = document.getElementById("ingredients");
            setIngredients([input.value, ...ingredients])
            console.log(ingredients)
        }
    };
    return (
        <div>
        {/*<Paper elevation={12}>*/}
            <div className="upload-recipe">
                <form>
                    <label htmlFor="form-title" className="form-title">
                        Share to the Community <br/>
                        <input id="recipe-name" type="text" value={recipeName} placeholder="Recipe name"
                        onChange={e => setRecipeName(e.target.value)}
                        />
                    </label>
                    <label htmlFor="upload-image" className="upload-image">
                        Upload image <br/>
                        <input id="upload-image" type="file" value={selectedFile}
                        onChange={e => setSelectedFile(e.target.files[0])}
                        />
                    </label>
                    <label htmlFor="ingredients" className="ingredients">
                        Ingredients <br/>
                        <input id="ingredients" type="text" placeholder="Write ingredients"
                        onKeyPress={handleEnterKeyPress} />
                    </label>
                    <div className="return-ingredients-list">
                        {ingredients}
                    </div>
                </form>
            </div>
        {/*</Paper>*/}
        </div>
    );
};

ReactDOM.render(
  <div>
    DEMO
    <CRBUploadRecipe />
  </div>,
  document.getElementById("rd")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="rd" />
<div id="ingredients"></div>

Solution

first of all don’t use document.getElementById("ingredients") in react app.
second of all you can put each ingredient in paragraph or div;

import { useState} from "react";
import {Paper} from "@material-ui/core";

const CRBUploadRecipe = () => {
const [recipeName, setRecipeName] = useState("");
const [selectedFile, setSelectedFile] = useState(undefined);
const [ingredients, setIngredients] = useState([]);

const handleEnterKeyPress = (e) => {
    if(e.which === 13) {
        const input = e.target; // your handler already has access to input;
        setIngredients((prev) => [input.value, ...prev])
        console.log(ingredients)
    }
}
return (
    <Paper elevation={12}>
        <div className="upload-recipe">
            <form>
                <label htmlFor="form-title" className="form-title">
                    Share to the Community <br/>
                    <input id="recipe-name" type="text" value={recipeName} placeholder="Recipe name"
                    onChange={e => setRecipeName(e.target.value)}
                    />
                </label>
                <label htmlFor="upload-image" className="upload-image">
                    Upload image <br/>
                    <input id="upload-image" type="file" value={selectedFile}
                    onChange={e => setSelectedFile(e.target.files[0])}
                    />
                </label>
                <label htmlFor="ingredients" className="ingredients">
                    Ingredients <br/>
                    <input id="ingredients" type="text" placeholder="Write ingredients"
                    onKeyPress={handleEnterKeyPress} />
                </label>
                <div className="return-ingredients-list">
                    {ingredients.map((ingridient, id) => (<p key={id}>{ingridient}</p>)}
                </div>
            </form>
        </div>
    </Paper>
);
}

   export default CRBUploadRecipe;

Answered By – I-vasilich-I

Answer Checked By – Clifford M. (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.