如何将Redux动作传递给2个reducer以更新React中的状态?

问题描述 投票:0回答:1

我的应用程序在CurrentStatus组件中有一个可单击的项目,该项目将service.id传递给父组件Dashboard,并通过Redux动作使用service_notes来获取axios.getservice_notes被传递到减速器和Redux存储中。然后,我将connect移至ServiceLogs组件中的存储,并遍历数组以在DOM上的render()中显示。 ServiceLogs是注释类型的组件,用户可以在其中添加注释。我可以创建注释,但是无法更新状态。我最新的方法是采取CREATE_NOTE动作,并在notesReducerserviceNotesReducer中使用它。这仍然不会更新状态和DOM。

这是我的布局:

Dashboard_wirefram

以下是相关组件:

仪表板:

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组件,我在其中单击一项(服务),并将ID从get中的getServiceNotes(serviceId)函数中的Dashboard传递到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。我在这两个减速器中尝试过:

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操作。

reactjs redux react-redux state reducers
1个回答
0
投票

也许您应该遵循Redux样式指南的建议:https://redux.js.org/style-guide/style-guide我想这个想法是为整个应用程序只保留一个商店,您应该使用该组件将与商店的连接包装在一个更高的层次上(就组件而言)。

enter image description here

我还建议您使用新的Redux Hooks,例如useSelector,并转换您的类组件以使用React Hooks简化代码。https://reactjs.org/docs/hooks-intro.html

© www.soinside.com 2019 - 2024. All rights reserved.