В моем приложении есть компонент, активируемый нажатием кнопки CurrentStatus
, который передает service.id
родительскому компоненту Dashboard
и получает service_notes
через действие Redux с axios.get
. service_notes
передаются в редуктор и в хранилище Redux. Затем я connect
в хранилище в ServiceLogs
компоненте и перебираю массив для отображения в render()
на DOM. ServiceLogs
- это компонент типа комментариев, в который пользователь может добавлять заметки. Я могу создавать заметки, но не могу обновить состояние. Моим последним подходом было выполнение действия CREATE_NOTE
и использование его в notesReducer
AND serviceNotesReducer
. Это все еще не обновляет состояние и DOM.
Вот мой макет:
![Dashboard_wirefram](https://i.stack.imgur.com/Dr9yc.png)
Вот соответствующие компоненты:
Панель инструментов:
import React, { Component } from "react";
import { connect } from "react-redux";
import { Container, Grid, Button } from "semantic-ui-react";
import CurrentStatus from "./components/CurrentStatusComponent";
import KnownOutages from "./components/KnownOutagesComponent";
import ServiceLogs from "./components/ServiceLogsComponent";
import { getServices } from "./actions/getServicesAction";
import { getServiceNotes } from "./actions/getServiceNotesAction";
import { getOutages } from "./actions/getOutagesAction";
class Dashboard extends Component {
state = {
serviceNotes: null,
serviceOutages: null,
showServiceLogs: "none",
}
componentDidMount() {
this.props.getServices();
this.props.getOutages();
}
displayServiceLogs = serviceId => {
debugger
this.props.getServiceNotes(serviceId)
this.setState({ showServiceLogs: "none" ? "block" : "none"});
}
render() {
console.log(this.state)
return (
<>
<Container fluid>
<h1>TML Dashboard</h1>
</Container>
<Grid columns={3} divided>
<Grid.Row>
<Grid.Column width={5}>Service Log</Grid.Column>
<Grid.Column width={6}>Current Status</Grid.Column>
<Grid.Column width={3}>Known Outages</Grid.Column>
</Grid.Row>
<Grid.Row>
<Grid.Column width={5}>
<ServiceLogs showServiceLogs={this.state.showServiceLogs}/>
</Grid.Column>
<Grid.Column width={6}>
<CurrentStatus displayServiceLogs={this.displayServiceLogs}/>
</Grid.Column>
<Grid.Column width={3}>
<KnownOutages />
</Grid.Column>
</Grid.Row>
</Grid>
</>
);
}
}
const mapStateToProps = state => {
return {
services: state.services.services,
notes: state.notes.notes
}
}
const mapDispatchToProps = dispatch => {
return {
getServices: () => dispatch(getServices()),
getNotes: () => dispatch(getNotes()),
getOutages: () => dispatch(getOutages()),
getServiceNotes: serviceId => dispatch(getServiceNotes(serviceId))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Dashboard);
Вот компонент CurrentStatus
, в котором я щелкаю элемент (услугу) и передаю идентификатор на панель инструментов в get
из функции getServiceNotes(serviceId)
в getServiceNotesActoin
:
import React, { Component } from "react";
import { connect } from "react-redux";
import { Table, Header } from "semantic-ui-react";
const uuidv4 = require("uuid/v4")
class CurrentStatus extends Component {
handleClick = serviceId => {
this.props.displayServiceLogs(serviceId)
}
render() {
console.log(Object.keys(this.props.services))
return (
<>
<Table celled padded>
<Table.Header>
<Table.Row>
<Table.HeaderCell singleLine>Service</Table.HeaderCell>
<Table.HeaderCell>Status</Table.HeaderCell>
<Table.HeaderCell>Reason</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
{Object.assign(this.props.services).map((service) => (
<Table.Row key={uuidv4()}>
<Table.Cell
onClick={() => this.handleClick(service.id)}
>
<Header as="h3" textAlign="center">
{service.name}
</Header>
</Table.Cell>
<Table.Cell textAlign="center">
{service.is_down ? (
<h4 style={{ color: "red" }}>Down</h4>
) : (
<h4 style={{ color: "green" }}>Up</h4>
)}
</Table.Cell>
<Table.Cell></Table.Cell>
</Table.Row>
))}
</Table.Body>
</Table>
</>
);
}
};
const mapStateToProps = state => {
return {
services: state.services.services
}
};
export default connect(mapStateToProps, null)(CurrentStatus);
, а вот компонент ServiceLogs
, где я могу отображать и отображать связанные serviceNotes
:
import React, { Component } from "react";
import { connect } from "react-redux";
import { Comment, Container, Grid, Form, Button } from "semantic-ui-react";
import { createNote } from "../actions/createNoteAction";
class ServiceLogsComponent extends Component {
state = {
entry: ""
}
handleChange = (e, { name, value }) => this.setState({ [name]: value })
handleSubmit = e => {
e.preventDefault()
const userId = 2
const serviceId = this.props.serviceNotes[0].service.id
this.props.createNote(this.state.entry, serviceId, userId)
}
render() {
console.log(this.props)
return (
<>
<div style={{ display: this.props.showServiceLogs }}>
<Comment>
<Comment.Group>
{this.props.serviceNotes.map((serviceNote) => (
<Comment.Content>
<Comment.Author as="a">{serviceNote.created_at}</Comment.Author>
<Comment.Metadata>{serviceNote.user.username}</Comment.Metadata>
<Comment.Text>{serviceNote.entry}</Comment.Text>
</Comment.Content>
))}
<Form onSubmit={(e) => this.handleSubmit(e)}>
<Form.TextArea
style={{ height: "50px" }}
onChange={this.handleChange}
name="entry"
/>
<Form.Button
type="submit"
content="Add Note"
labelPosition="left"
icon="edit"
primary
/>
</Form>
</Comment.Group>
</Comment>
</div>
</>
);
}
}
const mapStateToProps = state => {
return {
services: state.services.services,
notes: state.notes.notes,
serviceNotes: state.serviceNotes.serviceNotes
};
};
const mapDispatchToProps = dispatch => {
return {
createNote: (entry, serviceId, userId) => dispatch(createNote(entry, serviceId, userId))
}
};
export default connect(mapStateToProps, mapDispatchToProps)(ServiceLogsComponent);
Поэтому я не могу обновить DOM при создании новой заметки. Я пробовал это в этих 2 редукторах:
const initialState = {
notes: [],
};
export const notesReducer = (state = initialState, action) => {
switch (action.type) {
case "GET_NOTES":
return { ...state, notes: action.payload };
case "CREATE_NOTE":
return {
...state,
notes: [...state.notes, action.payload],
};
default:
return state;
}
};
и
const initialState = {
serviceNotes: [],
};
export const serviceNotesReducer = (state = initialState, action) => {
switch (action.type) {
case "GET_SERVICE_NOTES":
return { ...state, serviceNotes: action.payload };
case "CREATE_SERVICE":
return { ...state, serviceNotes: [ ...state.serviceNotes, action.payload] }
default:
return state;
}
};
Надеюсь, это достаточно ясно Вкратце: мне нужно ServiceLogs
состояние, чтобы изменить действие CRUD.