user14419627
user14419627

Reputation:

How to conditionally show element in react JSX?

I am creating a UI dynamically using JSON data which renders input or textarea elements conditionally.

Sample JSON Data

[
  {
    type: "input",
    val: "input text",
    name: "Input Field",
    editable: false
  },
  {
    type: "text",
    val: "text area text",
    name: "Text area field",
    editable: true
  },
  {
    type: "text",
    val: "text area text",
    name: "Text area field",
    editable: true
  }
];

Issues

I tried using index and matching with index, but that also did not work.

My code

{data.map((li, index) => (
      <div className="col-12 col-sm-12 col-md-6 col-lg-6 col-xl-6">
        {li.type === "input" && (
          <div className="divCont">
            {li.editable && disabled && (
              <span onClick={editComp}>Edit</span>
            )}
            <input
              type="text"
              className="form-control"
              disabled={disabled}
              defaultValue={li.val}
            />
          </div>
        )}

        {li.type === "text" && (
          <div className="divCont">
            {li.editable && disabled && (
              <span onClick={(e) => editComp(index)}>Edit</span>
            )}
            {disabled === false && ind === index && (
              <span onClick={editComp}>Send</span>
            )}
            <input
              type="text"
              className="form-control"
              disabled={disabled}
              defaultValue={li.val}
            />
          </div>
        )}
      </div>
    ))}

Code sandbox

Edit / Update

What I am trying to do

Upvotes: 0

Views: 173

Answers (2)

fxdxpz
fxdxpz

Reputation: 1989

Okay, I understand that you probably new to React and maybe even programming. Learning is good. Here some updated version of your code which does what you wanted, at least the way I have understood. Note though, I have no idea what you trying to build here, but hopefully it will give you some new start:

import React, { useState } from "react";
import "./styles.css";
import "bootstrap/dist/css/bootstrap.min.css";

function EditableArea({ val, ...rest }) {
  const [disabled, setDisabled] = useState(true);
  const [value, setValue] = useState(rest.value);

  const handleSend = () => {
    // ... send it somewhere maybe?..
    console.log(value);
    setDisabled(true);
  };

  return (
    <div className="divCont">
      {disabled ? (
        <span onClick={() => setDisabled(false)}>Edit</span>
      ) : (
        <span onClick={handleSend}>Send</span>
      )}
      <textarea
        type="text"
        className="form-control"
        disabled={disabled}
        placeholder={rest.placeholder}
        onChange={(e) => setValue(e.target.value)}
        value={value}
      ></textarea>
    </div>
  );
}

function Editable({ ...rest }) {
  const [disabled, setDisabled] = useState(true);
  const [value, setValue] = useState(rest.value || "");

  const handleSend = () => {
    // ... send it somewhere maybe?..
    console.log(value);
    setDisabled(true);
  };

  return (
    <div className="divCont">
      {disabled ? (
        <span onClick={() => setDisabled(false)}>Edit</span>
      ) : (
        <span onClick={handleSend}>Send</span>
      )}
      <input
        type="text"
        className="form-control"
        disabled={disabled}
        placeholder={rest.placeholder}
        value={value}
        onChange={(e) => setValue(e.target.value)}
      />
    </div>
  );
}

let data = [
  {
    type: "input",
    val: "input text",
    name: "Input Field",
    editable: false
  },

  {
    type: "text",
    placeholder: "text area text",
    name: "Text area field",
    editable: true,
    value: ""
  },
  {
    type: "text",
    placeholder: "text area text",
    name: "Text area field",
    editable: true,
    value: ""
  }
];

function redrerInput({ type, editable, ...rest }) {
  switch (type) {
    case "text":
      return <EditableArea {...rest} />;
    case "input":
      return <Editable {...rest} />;
    default:
      return null;
  }
}

export default function App() {
  return (
    <div className="App">
      <div className="row">
        {data.map((item, i) => (
          <div key={i} className="col-12 col-sm-12 col-md-6 col-lg-6 col-xl-6">
            {redrerInput(item)}
          </div>
        ))}
      </div>
    </div>
  );
}

Here is CodeSandbox fork

But I would strongly recommend to read documentation about React first.

Upvotes: -1

6uzm4n
6uzm4n

Reputation: 75

You are using the same flag 'disabled' to control the state of all your components. Therefore, when you click on send you change it to false for every field and that renders them all editable. The easiest fix would be to use a different flag for each field, but that may not scale well if you need it to.

Upvotes: 2

Related Questions