conset [reExport, setReExport] = useState([reExportPattern])
const modelFieldReExp = useRef([modelFieldReExpPattern])
function addReExportRawHandler() {
let nextReExport = [...reExport];
let newItem = reExportPattern();
nextReExport.push(newItem);
modelFieldReExp.current.push(modelFieldRegExpPattern);
setReExport(nextReExp);
}
function removeReExportRawHandler(e) {
var reIdx = e.target.parentNode.parentNode.getAttribute('reidx');
let nextReExport = [...reExport];
if (reExport.length > 1) {
modelFieldRegExp.current.pop()
nextReExport.splice(reIdx, 1);
setReExport(nextReExport);
}
}
const reExportPattern = () => {
let pattern = {
kodfito: '',
num: '',
date: '',
product: [{
production: {
id: null,
value: ''
},
netto: '',
unit: '',
country: {
id: null,
value: ''
}
}]
}
return pattern;
}
const [reExport, setReExport] = useState([reExportPattern()]);
const modelFieldRegExpPattern = {
kodfito: {
require: true,
regexp: /^\d+$/,
ref: useRef(null),
checked: false
},
num: {
require: true,
regexp: /^[\w\/-]{4,}$/,
ref: useRef(null),
checked: false
},
date: {
require: true,
regexp: null,
ref: useRef(null),
checked: false
},
product: {
production: {
require: true,
regexp: null,
ref: useRef(null),
checked: false
},
netto: {
require: true,
regexp: null,
ref: useRef(null),
checked: false
},
unit: {
require: true,
regexp: /^\d+$/,
ref: useRef(null),
checked: false
},
country: {
require: true,
regexp: null,
ref: useRef(null),
checked: false
}
}
}
const modelFieldRegExp = useRef([modelFieldRegExpPattern]);
function addReExportRawHandler() {
let nextReExp = [...reExport];
let newItem = reExportPattern();
nextReExp.push(newItem);
modelFieldRegExp.current.push(modelFieldRegExpPattern);
setReExport(nextReExp);
}
function removeReExportRawHandler(e) {
var reIdx = e.target.parentNode.parentNode.getAttribute('reidx');
let nextReExport = [...reExport];
if (reExport.length > 1) {
modelFieldRegExp.current.pop()
nextReExport.splice(reIdx, 1);
setReExport(nextReExport);
}
}
let rowsReExp = reExport.map((item, index) => {
let first = <tr key={index * 10} reidx={index} pidx={0} className='align-middle'>
<td rowSpan={reExport[index].product.length + 1}>
<div>
<Select
data={kodfito}
disabled={getKodfitoDisabled(index)}
name='kodfito'
value={reExport[index].kodfito}
handler={changeReExportHandler}
ref={modelFieldRegExp.current[index].kodfito.ref}
/>
</div>
<div className='mt-1'>
<input type='text' className="form-control ms-1" name='num' value={reExport[index].num}
onChange={changeReExportHandler} ref={modelFieldRegExp.current[index].num.ref}/>
</div>
</td>
<td rowSpan={reExport[index].product.length + 1}>
<input
type='date'
name='date'
className='form-control'
value={reExport[index].date}
onChange={changeReExportHandler}
ref={modelFieldRegExp.current[index].date.ref}
/>
</td>
<td>
<Autocomplete data={getProductionByField(index, 0, 're')} search={getProduction}
pIdx={0} outerIdx={index} name='production' section="re" value={reExport[index].product[0].production.value}
choiceHandler={choiceAutocomplete} ref={modelFieldRegExp.current[index].product.production.ref}/>
</td>
<td>
<input type='text' className="form-control" name='netto' value={reExport[index].product[0].netto}
onChange={changeReExportProductHandler} ref={modelFieldRegExp.current[index].product.netto.ref}/>
</td>
<td>
<Select
data={units}
name='unit'
value={reExport[index].product[0].unit}
handler={changeReExportProductHandler}
ref={modelFieldRegExp.current[index].product.unit.ref
}/>
</td>
<td>
<Autocomplete data={getCountryByField(index, 0, 're')} search={getCountry}
pIdx={0} outerIdx={index} name='country' section='re' value={reExport[index].product[0].country.value}
choiceHandler={choiceAutocomplete} ref={modelFieldRegExp.current[index].product.country.ref}/>
</td>
<td style={{width: 110}} className='small-text'><span className='link hover' onClick={createFssHandler}>создать ФСС</span></td>
<td style={{width: 130}} className='small-text'><span className='link hover' onClick={addIntoFssHandler}>добавить в ФСС</span></td>
<td style={{width: 30}}><span className='link hover' onClick={removeProductRowExpHandler}>x</span></td>
<td rowSpan={reExport[index].product.length + 1} className='align-middle' style={{width: 30}}>
<span className='link hover' onClick={removeReExportRawHandler}>x</span>
</td>
</tr>;
let middle = getReExpProductsRows(index);
let end = <tr key={index * 10 + 9} idx={index}>
<td colSpan='7' className='text-start position-relative'>
<span>Сумма: {sumProducts(reExport[index].product)}</span>
<span className="add-row" idx={index} onClick={addProductRowReExpHandler}>Добавить строку</span>
</td>
</tr>;
let delimiter = (index !== reExport.length - 1) ?
<tr key={index * 10 + 9.5}>
<td colSpan='10' className='delimiter'></td>
</tr> : null;
return [first, middle, end, delimiter]
}
)
return (
<div className='card bg-light shadow-sm p-2 m-2 mt-3'>
<div className="row align-items-start">
<span className="col-sm-1 col-form-label">Описание товаров:</span>
<div className="col d-inline-flex">
<table className="table table-bordered mb-0">
<thead className='fs-6'>
<tr className='table-th'>
<th style={{width: 220}}>Реэкспорт ФСС</th>
<th style={{width: 150}}>Дата выдачи</th>
<th>Товар</th>
<th style={{width: 100}}>Нетто</th>
<th style={{width: 100}}>Единицы</th>
<th style={{width: 330}}>Страна происхождения (для 06 <br/>группы вводиить страну отправления)</th>
<th colSpan='2'>Действия с ФСС</th>
<th colSpan='2'>Удалить</th>
</tr>
</thead>
<tbody>
{rowsReExp}
<tr className='border border-0'>
<td colSpan='10' className='delimiter border border-0 pt-1 pb-0'><span className='hover link' onClick={addReExportRawHandler}>Добавить реэкспортный ФСС</span></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
)
const [reExport, setReExport] = useState([structuredClone(reExportPattern)]);
function addReExportRawHandler() {
let nextReExp = [...reExport];
let newItem = structuredClone(reExportPattern);
nextReExp.push(newItem);
setReExport(nextReExp);
}
function setRef(el) {
reExport[item].num.ref = el
}
<input ref={setRef}>
const [reExport, setReExport] = useState([structuredClone(reExportPattern)]);
И если не сложно поясните про пвсевдо-рефы.
const [someRef] = useState({ current: null });
{ current: 'anything' }
.и так выдает ошибку el undefinded. Что-то не так делаю?)
Ты делаешь глубокое копирование при каждом ререндере. И это не имеет смысла, пока ты создаёшь объект внутри тела компонента.
А работает это потому, что ты таким образом создал псевдо-рефы.
function createRef() {
return {current: null}
}