Я хочу добавить машины в массив машин, поэтому я определил конкретный компонент с функцией добавления в нем. Поэтому, когда я добавляю «процесс» в массив «процессов», он отражается на консоли с помощью useEffect. Но когда я добавляю машину, это отражается в компоненте MachineGround, но не в компоненте приложения. В целом я планирую добавить панель инструментов, где даже если mcahine добавляется в массив компьютеров, это должно отражаться в процессах в компоненте приложения, и панель инструментов должна обновляться.
Я буду признателен за вашу помощь.
Компонент приложения
import React, { useEffect, useState } from 'react';
import { Container, Typography, Box, Button } from '@mui/material'
import MachineGround from './Components/MachineGround'
import { Process } from './types'
const App = () => {
const [processes, setProcesses] = useState<Process[]>([{
Name: 'Process-1', machines: [
{
Name: 'Machine-1', devices: [{
Name: 'device-1',
type: 'Timer'
}]
}]
}]) // dummy process
// const [processes, setProcesses] = useState<Process[]>([])
const [count, setCount] = useState<number>(1) // dummy process count.
// Add Process
const addProcess = () => {
if (processes.length < 10) {
setCount(count + 1)
const processNow: Process = {
Name: `Process-${count}`,
machines: []
}
setProcesses((process) => {
return (
[...process, processNow]
)
})
} else {
alert("Limit can't exceeds 10")
}
}
// Delete Process
const deleteProcess = (passProcess: Process) => {
setProcesses(processes.filter((process) => process.Name !== passProcess.Name))
}
useEffect(() => {
console.info(processes)
}, [processes])
return (
<>
<Container maxWidth='lg'>
<Typography variant='h3' mt = {5} sx = {{ fontWeight: 700 }} align = {'center'} gutterBottom>
My DashBoard
</Typography>
<Box sx = {{ bgcolor: '#F4F4F7', paddingInline: 5, borderRadius: 10 }} >
{/* here will be the renders of processes */}
{
processes.map((process) => (
<Box>
<Box sx = {{ display: 'flex', justifyContent: 'space-between' }} pb = {2} pt = {2}>
<Typography variant='h6' >
{process.Name}
</Typography>
<Button variant='contained' onClick = {() => {
deleteProcess(process)
}}>
Delete
</Button>
</Box>
<MachineGround process = {process} />
</Box>
))
}
</Box>
<Button variant='contained' color='primary' sx = {{ marginBlock: 5, marginLeft: 10 }} onClick = {addProcess}> Add Process</Button>
</Container>
</>
);
}
export default App;
import React, { useEffect, useState } from 'react'
import DeviceGround from './DeviceGround'
import { Box, Typography, Button } from '@mui/material'
//types
import { Machine, Process } from '../types'
type Props = {
process: Process
}
const MachineGround = ({ process }: Props) => {
const [count, setCount] = useState<number>(1)
const [machines, setMachines] = useState<Machine[]>(process.machines)
const handleAddMachine = () => {
if (machines.length < 10) {
const newMachine: Machine = { Name: `Machine-${count}`, devices: [] }
setMachines((machines) => [...machines, newMachine])
setCount(count + 1)
} else {
alert("You can't add more than 10 Machines.")
}
}
const handleDeleteMachine = (machine: Machine) => {
setMachines(machines.filter((current) => current.Name !== machine.Name))
}
useEffect(() => {
console.info('machines Array Changed')
}, [machines])
return (
<Box sx = {{ bgcolor: '#00e676', borderRadius: 5 }} mt = {2} ml = {3} mr = {3} pt = {1} pb = {1} mb = {2}>
{machines.map((machine: Machine) => {
return (
<>
<Box sx = {{ display: 'flex', justifyContent: 'space-between' }} mt = {2}>
<Typography paragraph ml = {5} sx = {{ fontWeight: 700 }}>
{machine.Name}
</Typography>
<Button variant='outlined' size='small' sx = {{ marginRight: 5 }} onClick = {() => {
handleDeleteMachine(machine)
}}>Delete Machine</Button>
</Box>
<Box>
{/* {
machine.devices.length !== 0 ?
<DeviceGround machine = {machine}></DeviceGround>
: null we dont need conditional render
} */}
<DeviceGround machine = {machine} />
</Box>
</>
)
})}
<Button variant='contained' size='small' sx = {{ marginLeft: 5 }} onClick = {handleAddMachine}>Add Machine</Button>
</Box >
)
}
export default MachineGround
Я думаю, что я должен использовать Redux? или другое госуправление то что мне делать? Я перепутал штаты.
Инструменты управления состоянием, такие как Redux, Context-API, могут быть здесь хорошим вариантом, но даже если вы не хотите их использовать, вы можете использовать обычные функции javascript. Просто передайте их в качестве реквизита от вашего родительского компонента к дочернему компоненту. Я объясню, что я имею в виду здесь. Напишите функцию в своем родительском компоненте, которая принимает объект машины и обновляет массив машин. Теперь передайте этот компонент в качестве реквизита вашему дочернему компоненту. Теперь внутри вашего дочернего компонента вызовите эту функцию с объектом машины, который вы хотите добавить в массив машин. И бум, ваш массив машин в родительском будет обновлен. Надеюсь это поможет! :-)
В любом случае, большое спасибо, это лучший ответ, я должен был использовать Redux или контекстный API.
Спасибо, hardit, это сработало, и теперь меня беспокоит только то, как это должно отражать использование useEffect в консоли, если отдельная машина изменяется в определенном процессе в компоненте приложения.