Bigred
Bigred

Reputation: 47

Rendering an array of data in React

I am trying to render some filtered xml data into a web page. The data is in an array and is pictured below.

Xml Data format

This is my code at the minute but I am very lost. I have tried many different variation but they all seem to result in:

  1. either not rendering anything to the webpage
  2. a error stating that resValue "cannot be used as a child" or something along those lines.

Currently this code doesn't bring up any faults - it just doesn't render the array.

I am new to React and web development in general.

Any help would be greatly appreciated. Thanks.

export default function Home() {
  // State to store value from the input field
  const [resValue, setResVal] = useState("");

  // Input Field handler
  function handleRes(event) {
    setResVal((resValue) => event);
    console.log(resValue);
    return (
      <div>
        <ul>
          {resValue.map((item) => {
            return <li>{item}</li>;
          })}
        </ul>
      </div>
    );
  }

  // State to store value from the input field
  const [inputValue, setInputValue] = useState("");

  // Input Field handler
  const handleUserInput = (e) => {
    setInputValue(e.target.value);
  };

  // Reset Input Field handler
  const resetInputField = () => {
    setInputValue("");
  };

  return (
    <>
      <div className="InsideContent">
        <Input
          className="input1"
          placeholder="Paste PoB Code"
          name="pobCode"
          value={inputValue}
          onChange={handleUserInput}
        />
      </div>

      <div className="InsideContent">
        <Button1 onClick={() => handleRes(loadPoBXml(inputValue))}>
          Confirm
        </Button1>
        <Button2 onClick={resetInputField}>Reset</Button2>
      </div>
    </>
  );
}

EDIT: Phil has said that to properly fix this I need to make my loadPoBData method synchronous. So here it is I also added my decodePoBString method too.

function loadPoBXml(str) {
var res = decodePoBString(str)
var xml = new XMLParser().parseFromString(res);   
let gem = (xml.getElementsByTagName('Gem'));
let item = (xml.getElementsByTagName('Item'))
return gem}

function decodePoBString(str) {
return inflateSync(new Buffer(str, "base64")).toString()

Upvotes: 1

Views: 192

Answers (1)

Phil
Phil

Reputation: 165034

The main issue is that you're trying to render something in the return value for an event handler. This won't work because any return value is ignored / discarded.

Rendering should be done in the return value of your component. Assuming loadPoBXml() is synchronous, all you need to do is have it set your resValue state and map over it in your JSX.

export default function Home() {
  // If resValue is meant to be an array, initialise it as one
  const [resValue, setResVal] = useState([]);
  const [inputValue, setInputValue] = useState("");

  // Confirm button click handler
  const handleClick = () => {
    setResVal(loadPoBXml(inputValue));
  };

  // Input Field handler
  const handleUserInput = (e) => {
    setInputValue(e.target.value);
  };

  // Reset Input Field handler
  const resetInputField = () => {
    setInputValue("");
  };

  return (
    <>
      <div className="InsideContent">
        <Input
          className="input1"
          placeholder="Paste PoB Code"
          name="pobCode"
          value={inputValue}
          onChange={handleUserInput}
        />
      </div>

      {/* assuming you want to render resValue here */}
      {resValue.length > 0 && (
        <div>
          <ul>
            {resValue.map((item, i) => (
              <li key={`item${i}`}>{item.name}</li>
            ))}
          </ul>
        </div>
      )}

      <div className="InsideContent">
        <Button1 onClick={handleClick}>Confirm</Button1>
        <Button2 onClick={resetInputField}>Reset</Button2>
      </div>
    </>
  );
}

Upvotes: 1

Related Questions