Update:
This is a codesandbox example!
I have a textarea component in which I'm preforming validation, line by line:
The error messages in the UI are a collection of objects which have an id property based on the row the text is on and a message property which will house the error. e.g. {id: 1, message: 'error message', name: 'text from line'}
From what I understand you can't set state in a loop as the results are not guaranteed.a
This is the setMessage function which gets the string:
setMessage is being called inside my validation function:
function setMessage(data) { console.log('data', data); console.log("arrFromVariableTypeNameString ", arrFromVariableTypeNameString); let allMessages = [...messagesContainer]; function drop(data, func) { var result = []; for (var i = 0; i < data.length; i++) { var check = func(data[i]); console.log("check ", check); if (check) { console.log("i + 1 ", i + 1); result = data.slice(i, i + 1); break; } } return result; } for (var i = 0; i < arrFromVariableTypeNameString.length; i++) { var match = drop(allMessages, e => e.id === i + 1); if (match?.length) { match[0] = { ...match[0], ...{ message: data, name: arrFromVariableTypeNameString[i] } } console.log("match ", match); console.log("allMessages ", allMessages); allMessages = allMessages.map(t1 => ({ ...t1, ...match.find(t2 => { console.log("t2.id === t1.id ", t2.id === t1.id); return t2.id === t1.id }) })) } else { allMessages.push({ name: arrFromVariableTypeNameString[i], id: i + 1, message: data }) } } setMessagesContainer(allMessages) } This is the whole component:
export function VariableSetupModal({ exisitingVariableTypes }) { const dispatch = useDispatch(); const [isOpen, setIsOpen] = useState(); const [variableTypeName, setVariableTypeName] = useState(''); const [clipboardData, setClipboardData] = useState('') const [pasted, setIsPasted] = useState(false) const [messages, setMessages] = useState(''); const [messagesContainer, setMessagesContainer] = useState([]); var arrFromVariableTypeNameString = variableTypeName.split('\n'); useEffect(() => { function setMessage(data) { console.log('data', data); console.log("arrFromVariableTypeNameString ", arrFromVariableTypeNameString); let allMessages = [...messagesContainer]; function drop(data, func) { var result = []; for (var i = 0; i < data.length; i++) { var check = func(data[i]); console.log("check ", check); if (check) { console.log("i + 1 ", i + 1); result = data.slice(i, i + 1); break; } } return result; } for (var i = 0; i < arrFromVariableTypeNameString.length; i++) { var match = drop(allMessages, e => e.id === i + 1); if (match ? .length) { match[0] = { ...match[0], ...{ message: data, name: arrFromVariableTypeNameString[i] } } console.log("match ", match); console.log("allMessages ", allMessages); allMessages = allMessages.map(t1 => ({ ...t1, ...match.find(t2 => { console.log("t2.id === t1.id ", t2.id === t1.id); return t2.id === t1.id }) })) } else { allMessages.push({ name: arrFromVariableTypeNameString[i], id: i + 1, message: data }) } } setMessagesContainer(allMessages) } function validator(variableType) { var data = { variableType: variableType, } var rules = { variableType: "regex:^[a-zA-Z0-9_ ]+$|min:3|max:20", } var messages = { min: `Enter at least three characters.`, max: `Don't exceed more than twenty characters.`, regex: `No special characters (but spaces) allowed.` } validate(data, rules, messages) .then(success => { console.log('Variable Type Entered correctly.', success) setMessage(''); return }) .catch(error => { console.log('error', error) setMessage(error[0].message); return }); } function checkIfArrayIsUnique(myArray) { if (myArray.length === 50) setMessages('Only 50 Variable Types allowed.'); return myArray.length === new Set(myArray).size; } arrFromVariableTypeNameString.map((variableType, i, thisArr) => { function findDuplicates(uniqueCount) { var count = {}, result = ''; uniqueCount.forEach((i) => { count[i] = (count[i] || 0) + 1; }); console.log(count); return Object.keys(count).map((k) => { if (count[k] > 1) return result.concat(`Variable Type ${k}: appears ${count[k]} times.`) }).filter((item) => item !== undefined) } if (checkIfArrayIsUnique(thisArr)) { if (validator(variableType)) { return thisArr; } } else { setMessage(findDuplicates(thisArr).map(s => < > { s } < br / > < />)); return; } }) return () => { setMessagesContainer([]) console.log("messagesContainer clean up ", messagesContainer); } }, [variableTypeName]) const handlePaster = (e) => { e.persist() setIsPasted(true); setClipboardData(e.clipboardData.getData('text')); } const handleChange = (e) => { e.persist() var { keyCode } = e; var { value } = e.target; if (keyCode === 13) { setVariableTypeName(`${value}\n`); return; } else if ((pasted == true) && (keyCode == 13)) { setVariableTypeName(`${variableTypeName.concat(clipboardData)}\n`); setIsPasted(false); return; } else if ((pasted == true) && (keyCode !== 13)) { setVariableTypeName(`${variableTypeName.concat(clipboardData)}`); setIsPasted(false); return; } else { setVariableTypeName(`${value}`); return; } } return ( < div > < Button className = "button" onClick = { evt => setIsOpen(true) } > Add Variable Types < /Button> < div style = { { display: "none" } } > < Modal id = "myModal" heading = "Variable Type Configuration" description = "" userClosable = { true } autoFocus = { false } actionsLeft = { < React.Fragment > < Button display = "text" onClick = { handleCancel } > Cancel < /Button> < Button display = "primary" onClick = { handleSave } > Save < /Button> < /React.Fragment> } isOpen = { isOpen } onRequestClose = { detail => { handleCancel(false); setMessagesContainer([]) } } > { exisitngVarFormatted != "" && < Textbox as = "textarea" type = "text" value = { exisitngVarFormatted } disabled > Existing < /Textbox>} < Textbox as = "textarea" type = "text" placeholder = "Variable Types" maxLength = "100" value = { variableTypeName } onPaste = { e => handlePaster(e) } onChange = { e => handleChange(e) } > To Create < /Textbox> { messagesContainer.map((messageObj, i, arr) => { console.log("messageObj ", messageObj); return messageObj.message != '' ? ( < p key = { messageObj.id } className = "Messages" > { `Error on line ${i + 1}: ${messageObj.message}` } < /p> ) : null }) } < /Modal> < /div> < /div > ); } And this is what is having me pulling what's left of my hair out.
In the logs, you can clearly see the objects getting set correctly but then in the UI, the messages are not unique! Line 70
Any help would be appreciated!


iwith the blue background and read what the tooltip says. Consider usingconsole.log(JSON.stringify(variable, null, 2))if the object supports serialization.setStateor hooks in the code right now, so it may be I'm missing something.