Reputation: 924
How does one take user data from the page and use it to create elements in a react.js program?
I have a file, app.js. The first things declared in the file are a couple of constants, for toy data:
const book1 = [
{id: uuid(), content: 'reflections'}
];
const book2 = [
{id: uuid(), content: 'arising'},
]
and a single constant pulling them in as columns
const clusterColumns =
{
[uuid()]: {
name: 'Book 1',
items: book1
},
[uuid()]: {
name: 'Book 2',
items: book2
},
};
and a third const that cleans up the data as i move it around on the page
const onDragEnd = (result, columns, setColumns ) => {
if(!result.destination ) return;
const {source, destination} = result;
if (source.droppableId!==destination.droppableId) {
const sourceColumn = columns[source.droppableId];
const destColumn = columns[destination.droppableId];
const sourceItems = [...sourceColumn.items];
const destItems = [...destColumn.items];
const [removed] = sourceItems.splice(source.index, 1);
destItems.splice(destination.index, 0, removed);
setColumns({
...columns,
[source.droppableId]:{
...sourceColumn,
items: sourceItems,
},
[destination.droppableId]:{
...destColumn,
items: destItems
}
})
}
else {
const column = columns[source.droppableId];
const copiedItems = [...column.items];
const [removed] = copiedItems.splice(source.index, 1);
copiedItems.splice(destination.index, 0, removed)
setColumns({
...columns,
[source.droppableId]: {
...column,
items: copiedItems
}
})
}
};
a main bit of the app.js file is a nested function that builds drag and drop elements with some style, pulling in the toy data
function App() {
const [columns, setColumns] = useState(clusterColumns);
return (
<div>
<div style={{display: 'flex', justifyContent: 'left', height: '95%', position: "relative",
top: 5, left: 90, opacity: '27%'}}>
<DragDropContext onDragEnd={result => onDragEnd(result, columns, setColumns)}>
{Object.entries(columns).map(([id, column]) => {
return (
<div style={{display: 'flex', flexDirection: 'column', alignItems:'center',
fontFamily: 'Montez, sans-serif', color: '#913aff', fontSize: 27, padding:5, borderRadius: '19px',
}}><h2 style={{fontSize:(19*3), height: 45}}>{column.name}</h2>
<h2 style={{fontSize:(19*3), height: 45, top:'9px', position:'absolute', opacity:'60%', color:'#ffa0f9'}}>{column.name}</h2>
<div style={{margin: 2}}>
<Droppable droppableId={id} key={id} >
{(provided, snapshot) => {
return (
<div {...provided.droppableProps}
ref={provided.innerRef}
style={{
padding: 9,
width: 190,
minHeight: 9,
opacity: '95%',
borderRadius: '9px',
background: 'linear-gradient(to right bottom, rgba(196, 181, 255, 1), rgba(132,47,0,0.27)'}} >
{column.items.map((item, index) => {
return (
<Draggable key={item.id} draggableId={item.id} index={index}>
{(provided, snapshot) => {
return (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={{
opacity: '95%',
userSelect: 'none',
padding: 19,
margin: '0px 0px 3px 0px',
backgroundColor: snapshot.isDragging ? '#54ffff':'#b3f542',
background: 'linear-gradient(to right bottom, rgba(84, 255, 255, 0.63), rgba(179, 245, 66, 0.81)',
color: 'rgb(115,38,0)' ,
fontFamily: 'Montez',
fontSize: 36,
borderRadius: '9px',
...provided.draggableProps.style
}}>
{item.content}
</div>
)
}}
</Draggable>
)
}
)}
{provided.placeholder}
</div>
)
}}
</Droppable>
</div>
</div>
)
})}
</DragDropContext>
</div>
</div>
);
}
My question is, what might I build in, to replace the toy data with a button that the user enters new data into, which then might appear on-screen? I have tried putting a second program, for adding a cell.
class Cell extends React.Component {
render() {
return (
<form>
<input
type="text" style={{
display:'flex',
position:'relative',
top: '-360px',
right:'95px',
fontFamily: "VT323",
width:'144px',
fontSize:'36px',
color: 'rgb(115,38,0)',
opacity:'60%',
borderRadius: '9px',
height: '45px',
background: 'radial-gradient(rgba(196, 181, 255, .9), rgba(168,255,0,0.19)',
borderColor: 'rgba(255,255,255,0)'
}}
/>
</form>
);
}
}
But it is a simple user form; the data entered should effective replace the toy data filling the consts at the top of the first program.
Upvotes: 0
Views: 442
Reputation: 4268
Sample of adding a very basic input to add new items
Create a component for your input fields
function AddBookItem({ onAdd }) {
const [value, setValue] = useState('');
const onChange = ({ target: { value }}) => setValue(value);
return (
<div>
<input value={value} onChange={onChange} placeholder="Book Item" />
<button onClick={onAdd(value)}>Add book item</button>
</div>
);
}
Create a function to handle adding values to your parent state
const onAdd = (value) => () => {
setColumns((columns) => {
const nC = {...columns};
// get first book id
const id = clusterKeys[0];
const c = { ...columns[id] }
// console.log({ c });
const ci = [...c.items];
ci.push({ id: uuid(), content: value });
c.items = ci;
nC[id] = c;
return nC;
})
}
Add your new component to your app
<AddBookItem onAdd={onAdd} />
https://codesandbox.io/s/stackoverflow-add-example-kfk2e
Upvotes: 1