简体   繁体   English

在 ReactJS 中使用 useState 时出现问题:更新页面上的组件

[英]Having an issue with using useState in ReactJS: updating the component on page

Moved it all to the one file so I could copy-paste it in here.将其全部移动到一个文件中,以便我可以将其复制粘贴到此处。 So the issue coming in forcing ReactDOM re-render HTML table with useState().因此,强制 ReactDOM 使用 useState() 重新渲染 HTML 表时出现的问题。 As i understood useState is made to automatically update the innerHTML, force to render again or something like that.据我了解,useState 用于自动更新 innerHTML,强制再次呈现或类似的东西。

import React, {useState, useEffect} from 'react';
import ReactDOM from 'react-dom/client';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <App />
);

function App() {
    const [data, setData] = useState([]);
    useEffect(() => {
        fetch('/api/data')
        .then(response => response.json())
        .then(response => setData(response))
    }, []);
    if(data.length == 0){
      return (<>loading(if takes too long may crashed)</>);
    }
    var da = data;
    var headers = [da[0]];
    headers = headers.map(e => {return {name: e[0], spec_prof:e[1], enrl:e[2], drms:e[3], bdgt:e[4], edu_type:e[5], inst_type:e[6], cnct_inf:e[7], higher_or_scndry:e[8]}});
    headers = headers[0];
    da = da.slice(1, data.length);
    return(<>
    <Test_component hdrs={headers} data={da}/>
    </>);
};
  
const Test_component = function (data) {
    const [table, setTable] = useState(data.data);

    var headers = data.hdrs;
    var da = data.data;


    function Extra_filter_func() {
    var filters = document.getElementById('extras');
    filters.hidden = !filters.hidden
    };


    function Search() {
        var da = data.data;
        da = da.filter(e => e[0].includes(document.getElementById('namesearch').value));
        da = da.filter(e => e[1].includes(document.getElementById('specsearch').value));
        da = da.filter(e => e[2].includes(document.getElementById('on_base_of').value));
        if(document.getElementById('dorms').checked) {
            da = da.filter(e => e[3].includes('есть'));
        };
        if(document.getElementById('budget').checked) {
            da = da.filter(e => e[4].includes('да'));
        };
        da = da.filter(e => e[5].includes(document.getElementById('education_type').value));
        return(da);
      };


    if(headers.name != 'Название') {
      return(<> Ожидание таблицы </>);
    };
    da = da.map(e => {return {name: e[0], spec_prof:e[1], enrl:e[2], drms:e[3], bdgt:e[4], edu_type:e[5], inst_type:e[6], cnct_inf:e[7], higher_or_scndry:e[8]}});
    return (<>
      <input id='namesearch' placeholder='Поиск по названию'></input>
      <button onClick={() => setTable(Search())}> Поиск... </button>
  
      <p> <button id='extra_filter_btn' onClick={Extra_filter_func}> Дополнительные настройки поиска </button> </p>
      
      <div id='extras' hidden>
      <p> <input id='specsearch' placeholder='Поиск по специальностям и профессиям'></input> </p>
  
      <p> Можно поступить <select id="on_base_of">
      <option value=''>На базе 9/11</option>
      <option value='на базе 9 кл'>На базе 9</option>
      <option value='на базе 11 кл'>На базе 11</option>
      </select> </p>
      
      <p> Наличие общежития: <input id="dorms" type='checkbox'></input> </p>
  
      <p> Наличие бюджетных мест: <input type='checkbox' id="budget"></input> </p>
  
      <p> Тип обучения: <select id="education_type">
      <option value=''>Без разницы</option>
      <option value='очно'>очно</option>
      <option value='заочно'>заочно</option>
      <option value='очно/заочно'>очно/заочно</option>
      </select> </p>
      </div>
    <table className='tbl' id='tbl'>
        <thead>
        <tr>
          <th> {headers.name} </th>
          <th> {headers.spec_prof} </th>
          <th> {headers.enrl} </th>
          <th> {headers.drms} </th>
          <th> {headers.bdgt} </th>
          <th> {headers.edu_type} </th>
          <th> {headers.inst_type} </th>
          <th> {headers.cnct_inf} </th>
          <th> {headers.higher_or_scndry} </th>
        </tr>
        </thead>
        <tbody>
        {da.map((val, key) => {
              return (
                <tr key={key}>
                  <td>{val.name}</td>
                  <td>{val.spec_prof}</td>
                  <td>{val.enrl}</td>
                  <td>{val.drms}</td>
                  <td>{val.bdgt}</td>
                  <td>{val.edu_type}</td>
                  <td>{val.inst_type}</td>
                  <td>{val.cnct_inf}</td>
                  <td>{val.higher_or_scndry}</td>
                </tr>
              )
            })}
        </tbody>
      </table>
      </>);
};

So in Test_component() function I've created useState() hook 'const [table, setTable] = useState(data.data);'所以在 Test_component() function 我创建了 useState() hook 'const [table, setTable] = useState(data.data);' and assigned as initialState a list with lists inside that I'm getting from backend.并指定为 initialState 一个列表,其中包含我从后端获取的列表。 In the function Search() I'm filtering the variable(same list of lists) with values and then returning it straight into setTable().在 function Search() 中,我用值过滤变量(相同的列表列表),然后将其直接返回到 setTable() 中。

Had to add in Test_component()必须添加 Test_component()

if(headers.name != 'Название') {
  return(<> Ожидание таблицы </>);
};

and in App()在 App() 中

if(data.length == 0){
  return (<>loading(if takes too long may crashed)</>);
}

because of errors I was getting while data is not collected from backend, frontend even crashes.由于在未从后端收集数据时出现错误,前端甚至崩溃。 It doesn't connected with main issue anyhow, just wanted to clarify what are those checkers for in case you've questioned yourself with that.它无论如何都与主要问题无关,只是想澄清一下那些检查器的用途,以防您对此提出质疑。

I was trying to create second render on another div like this one, but I kind of don't know how it actually works so我试图在另一个像这样的 div 上创建第二个渲染,但我有点不知道它实际上是如何工作的

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <App />
);

but I kind of don't know how it actually works, so created something like that.但我有点不知道它实际上是如何工作的,所以创造了类似的东西。 First of all whole code looked a little bit different.首先,整个代码看起来有点不同。 In 'root' i was rendering just filters and search button while in 'table_root' i was rendering the table在“root”中,我只渲染过滤器和搜索按钮,而在“table_root”中,我渲染表格

const root = ReactDOM.createRoot(document.getElementById('table_root'));
root.render(
    <Test_component />
);

Unfortunately, it got stuck on checker that was blocking the whole code until request to backend wasn't finished.不幸的是,它卡在了阻止整个代码的检查器上,直到对后端的请求没有完成。 Probably because I've used useState wrong again.可能是因为我又用错了useState。 That was the only one idea I've got in mind to do.那是我唯一想做的想法。 I guess I just can't understand how exactly useState hook works and how to force re-render ReactDOM.我想我只是无法理解 useState 钩子究竟是如何工作的以及如何强制重新渲染 ReactDOM。

 const [data, setData] = useState([]);
    useEffect(() => {
        fetch('/api/data')
        .then(response => response.json())
        .then(response => setData(response))
    }, [data]);

Add data in dependancy array of useEffect may be you will find your solution在 useEffect 的依赖数组中添加数据可能会找到您的解决方案

Well the thing was just with好吧,事情只是

da = da.map(e => {return {name: e[0], spec_prof:e[1], enrl:e[2], drms:e[3], bdgt:e[4], edu_type:e[5], inst_type:e[6], cnct_inf:e[7], higher_or_scndry:e[8]}});

it should've look like它应该看起来像

da = table.map(e => {return {name: e[0], spec_prof:e[1], enrl:e[2], drms:e[3], bdgt:e[4], edu_type:e[5], inst_type:e[6], cnct_inf:e[7], higher_or_scndry:e[8]}});

was updating use useState thing but wasn't using it in rendering page.正在更新使用 useState 的东西,但没有在呈现页面中使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM