React-Redux:重新渲染过多

时间:2020-08-06 17:09:40

标签: reactjs redux react-redux react-hooks reducers

在我的react / redux应用程序中,我试图每次点击 AddBoxIcon 时弹出一个Modal。此刻我遇到了错误

错误:重新渲染次数过多。 React限制了渲染次数以防止无限循环。

第二个问题,我怀疑我配置 toggleModal 动作的方式可能是错误的。

我的方法不起作用。

// Toggle Modal action
export const toggleModal = () => (dispatch) => {
  dispatch({
    type: TOGGLE_MODAL,
  });
};

// Invoice Reducer
const initialState = {
  invoiceData: [],
  newInvoiceModal: false,
};

export default function (state = initialState, action) {
  switch (action.type) {
    case TOGGLE_MODAL:
      return {
        ...state,
        newInvoiceModal: !state.newInvoiceModal
      };

    case GET_INVOICE_DATA:
      return {
        ...state,
        invoiceData: action.payload,
      };

    case ADD_INVOICE_DATA:
      return {
        ...state,
        invoiceData: action.payload,
      };

    default:
      return state;
  }
}

发票表组件

import AddInvoiceModal from './AddInvoiceModal'
import { getInvoiceData, toggleModal } from "../../actions/customers/invoice";

const InvoiceTable = (props) => {
  const invoiceData = useSelector((state) => state.invoice.invoiceData);
  const newInvoiceModal = useSelector((state) => state.invoice.newInvoiceModal);  
  const dispatch = useDispatch(); 

  useEffect(() => {
    dispatch(getInvoiceData());
  }, [dispatch]);
  

  const classes = useStyles();

  const columns = [
    { name: "date", label: "Date" },
    { name: "invoiceOwner", label: "Name" },
    { name: "invoiceNo", label: "Invoice No" },
    { name: "product", label: "Product" },
  ];

  return (
    <div className={classes.root}>

      {/* ADD NEW EMPLOYEE MODAL */}
      <AddInvoiceModal 
        toggleModal={dispatch(toggleModal())} 
        newInvoiceModal={newInvoiceModal} 
      />

      <Grid container spacing={3}>
        <Grid item xs={12}>
          <Paper className={classes.paper}>
            <MUIDataTable
              title={
                <Fragment>
                  Purchase Invoice
                  <Tooltip title="Add">
                    <AddBoxIcon          <===== ADD ICON
                      color="action"
                      style={addIcon}
                      onClick={dispatch(toggleModal())}  <===== MODAL TRIGGER
                    />
                  </Tooltip>
                </Fragment>
              }
              data={invoiceData}
              columns={columns}
              options={options}
            />
          </Paper>
        </Grid>
      </Grid>
    </div>
  );
};

InvoiceTable.propTypes = {
  invoiceData: PropTypes.object.isRequired,
  getInvoiceData: PropTypes.func,
  toggleModal: PropTypes.func,
  newInvoiceModal: PropTypes.bool,
};

export default InvoiceTable;

模式文件

const AddInvoiceModal = (props) => {
    return (
      <div className="App container">
        <Modal isOpen={props.newInvoiceModal} scrollable={true}>
          <ModalHeader toggle={props.toggleModal}>Add Invoice</ModalHeader>
          <ModalBody>
            <h2>Hello</h2>
          </ModalBody>
          <ModalFooter>
            <Button
              color="primary"
            >
            Submit
            </Button>{" "}
            <Button
              color="secondary"
            >
              Cancel
            </Button>
          </ModalFooter>
        </Modal>
      </div>
    );

}

export default AddInvoiceModal;

1 个答案:

答案 0 :(得分:4)

老实说,我认为唯一的问题是这个

<template>
  <div class="voice">
    <div class="speech-to-txt" @click="startSpeechToTxt">Speech to txt</div>        
    <p>{{transcription_}}</p>
</div>
</template>



 <script>

  export default {
   name: 'speech_to_text',
   data() {
     return {
       runtimeTranscription_: "",
       transcription_: [],
       lang_: "es-ES"
     };
   },
   methods: {
    startSpeechToTxt() {
    // initialisation of voicereco
    
    window.SpeechRecognition =
    window.SpeechRecognition || 
    window.webkitSpeechRecognition;
    const recognition = new window.SpeechRecognition();
    recognition.lang = this.lang_;
    recognition.interimResults = true;

    // event current voice reco word
    recognition.addEventListener("result", event => {      
      var text = Array.from(event.results)
        .map(result => result[0])
        .map(result => result.transcript)
        .join("");
      this.runtimeTranscription_ = text;
    });
    // end of transcription
    recognition.addEventListener("end", () => {
      this.transcription_.push(this.runtimeTranscription_);
      this.runtimeTranscription_ = "";
      recognition.stop();
    });
     recognition.start();
   },

   }
  }
  </script>

需要成为

toggleModal={dispatch(toggleModal())} 

现在每个渲染器都会调用toggleModal={() => dispatch(toggleModal())} ,这将导致重新渲染,并再次调用