#javascript #reactjs #next.js #user-input
#javascript #reactjs #next.js #пользовательский ввод
Вопрос:
Я новичок в разработке, поэтому любая помощь приветствуется 🙂
Вот моя проблема:
Я использую next.js — это может быть важно, потому что, например, document.createElement, похоже, работает только с useEffect.
Я создал текстовую область, в которую пользователи добавляют слова, разделенные запятой (например, «Nike, Adidas, New Balance»). Я хочу переписать существующий код ниже, чтобы:
- таблица видна / появляется только тогда, когда пользователь добавляет что-то в поле ввода
- каждое слово из поля ввода (например. Nike, Adidas) создает новую строку в таблице (в заголовке таблицы «Бренд»).
К настоящему времени я пытался использовать .split и .Метод forEach для создания нового элемента (таблицы). Но я просто не могу заставить это работать — возможно, это просто неправильное решение. Любая помощь приветствуется!
function Analyzer() {
const [brand, setBrand] = React.useState('');
const handleChange = (event) => {
setBrand(event.target.value.split(','))};
return(
<div>
<textarea type="text"
placeholder="Example:
Nike, Adidas, New Balance ..."
onChange={handleChange}></textarea>
<table className={styles.table}>
<thead>
<tr>
<th>No.</th>
<th>Brand</th>
<th>Also known as</th>
<th>Avg. price</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>{brand}</td>
<td></td>
<td><input type= "number"></input>%</td>
</tr>
</tbody>
</table>
</div>);
}
Ответ №1:
Попробуйте что-то вроде следующего. Что я сделал, так это извлек Table
компонент и поместил в него любые условия для его рендеринга. Вы даже можете создать отдельный файл для этого компонента и передать ему любые соответствующие реквизиты.
Во-вторых, я помещаю список брендов в состояние как brands
внутри handleChange
функции. Затем эта переменная состояния повторяется .map
для отображения каждой строки в таблице.
function Analyzer() {
const [brands, setBrands] = React.useState([]);
const handleChange = ({ target }) => {
const { value } = target;
setBrands(value.split(','));
};
const Table = () => {
if (!brands || brands.length === 0) return null;
return (
<table className={styles.table}>
<thead>
<tr>
<th>No.</th>
<th>Brand</th>
<th>Also known as</th>
<th>Avg. price</th>
</tr>
</thead>
<tbody>
{brands.map((brand) => (
<tr>
<td>1</td>
<td>{brand}</td>
<td></td>
<td><input type= "number"></input>%</td>
</tr>
)}
</tbody>
</table>
);
};
return(
<div>
<input
onChange={handleChange}
placeholder="Example: Nike, Adidas, New Balance ..."
type="text"
value={brands}
/>
<Table />
</div>
);
};
Комментарии:
1. Спасибо за вашу помощь и объяснение! Думаю, я понял вашу идею. Я проверю это и дам обновление, если все получилось!
2. Я немного изменил код, проверка
!brands || brands === ''
никогда не будет работать, потому что вашеbrands
значение по умолчанию — массив. В любом случае, ваша функция map ничего не вернет, если массив пуст, поэтому нет необходимости проводить там проверку (таблица будет отображаться с 0 строкой данных). если вам нужна проверка, лучше проверить, является ли это пустым массивом.3. Я проверил код, и таблица работает отлично (только добавил необязательный индексный параметр в .map). Спасибо, ребята! Есть только небольшая проблема: я вижу заголовок таблицы, даже если ввода нет. Можно ли сделать ее невидимой в начале? Пытался переместить brands.map в начало, но затем заголовок отображается несколько раз.
4. Да, вот почему у меня было условие в начале компонента таблицы. Я отредактировал ее обратно (хотя и по-другому), чтобы проверить, есть ли элементы в массиве. Я сделал это, потому что мы вообще не хотим отображать таблицу, если нет ввода.
5. Отлично. Теперь все работает. Я сохранил ее как компонент в отдельном файле — спасибо за совет!