You won't be able to get access to this data in a React-type way, however you can get access to this data using plain JavaScript, which React supports. Basically you can't treat these inputs as controlled components, instead as uncontrolled components.
This means however that you won't get state updates in real time like you do with controlled components, but you can still get access to the data. You'll just have to get the data from the DOM when you need it (e.g. upon submission).
Since you also won't be able to pass refs directly to these components, you'll have to query the DOM. You can start with a ref for your container (the one whose inner HTML gets dangerously set) and then query for input elements (and/or the other input-like elements).
Here's an example:
App.js
export default function App() {
const dataContainerRef = React.useRef(null);
const handleSubmission = e => {
e.preventDefault();
const inputs = Array.from(dataContainerRef.current.querySelectorAll("input"));
// if your inputs have unique names:
const formData = Object.fromEntries(inputs.map(input => [input.name, input.value]));
// or just get an array of the values:
const formDataArray = inputs.map(input => input.value);
};
return (
<div className="App">
<Inner dataContainerRef={ dataContainerRef } />
<form onSubmit={handleSubmission}>
<div>Both two values comma separated: </div>
<button type="submit"> Submit </button>
</form>
</div>
);
}
Inner.js
export default function Inner(props) {
const { dataContainerRef } = props;
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<div
ref={dataContainerRef}
className="data-container"
dangerouslySetInnerHTML={{ __html: data.htmltag }}
/>
</div>
);
}
Here's a codesandbox demo.
Note that you can look into this question about getting form data with JS if you want to know about other ways you can get the form data using plain JS (I'd recommend not importing jQuery into your React project).
Alternate Approach
If you're open to changing the structure of your data so that that data is not an HTML string and instead is in JSON format, you can dynamically create the input elements yourself and control them like normal.
For example, if you structure data like this:
const data = {
inputNames: ["Hello", "Welcome"],
}
Then you can create formData of the form:
{
Hello: "",
Welcome: "",
}
which should be stored in the parent of Inner because it owns the submission function.
Then you'll just need to initialize the formData from data and then dynamically create an input element for each inputName given.
Here's a sample of Inner:
export default function Inner(props) {
const { formData, setFormData } = props;
React.useEffect(() => {
// initialize `formData`
setFormData(
Object.fromEntries(data.inputNames.map(inputName => [inputName, ""]))
);
}, [setFormData]);
const inputRows = data.inputNames.map(inputName => (
<tr key={inputName}>
<td>{inputName}</td>
<td>
<input
name={inputName}
value={formData[inputName]}
onChange={event => {
event.persist();
setFormData(prev => ({
...prev,
[event.target.name]: event.target.value
}));
}}
/>
</td>
</tr>
));
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<table>
<tbody>{inputRows}</tbody>
</table>
</div>
);
}
Here's a demo.
dangerouslySetInnerHTML? Would it be possible in your project to change the data to be in JSON format instead? If you're open to switching, I have some ideas on that as well.