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



将其全部移动到一个文件中,以便我可以复制粘贴到这里。所以问题来了,迫使ReactDOM用useState()重新渲染HTML表。据我所知,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>
</>);
};

所以在Test_component()函数中我创建了useState()钩子'const [table, setTable] = useState(data.data);'并赋值为initialState一个列表,里面有我从后端获得的列表。在函数Search()中,我用值过滤变量(相同的列表列表),然后将其直接返回到setTable()。

必须添加Test_component()

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

和in App()

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

因为我得到的错误,而数据不是从后端收集,前端甚至崩溃。无论如何,这与主要问题无关,只是想澄清一下这些检查器是用来做什么的,以防你对此有疑问。

我想在另一个div上创建第二次渲染,就像这个,但我不知道它是怎么工作的,所以

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

但是我不知道它是怎么工作的,所以创建了这样的东西。首先,整个代码看起来有点不同。在'root'中,我正在渲染过滤器和搜索按钮,而在'table_root'中,我正在渲染表

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

不幸的是,它卡住了检查器,阻塞了整个代码,直到请求后端还没有完成。可能是因为我又用错了useState。那是我脑子里唯一能想到的主意。我想我只是不明白useState钩子到底是如何工作的,以及如何强制重新渲染ReactDOM。

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

在useEffect的依赖数组中添加数据,也许你会找到你的解决方案

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]}});

应该看起来像

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]}});

正在更新use useState,但没有在渲染页面中使用它。

最新更新