setState()之后组件未重新呈现

时间:2018-08-20 09:53:58

标签: javascript reactjs

我的代码中包含以下组件:

class ContactsList extends Component {
   constructor(props) {
      super(props);
      this.state = {
         contactItems: [
            <ContactItem key="Lena" login="typeofweb1" name="Lena" department="JavaScript Developer" border="0" />,
            <ContactItem key="Brian" login="typeofweb2" name="Brian" department="Human Resources" />,
            <ContactItem key="Rick" login="typeofweb3" name="Rick" department="QA" />
         ]
      };
   }

   render() {
      return (
         <ul className="list-group list-group-flush container">
            {this.state.contactItems}
            <button type="button" onClick={this.addContactItem}>
               Add
            </button>
         </ul>
      );
   }

   addContactItem = () => {
      console.log(this.state.contactItems);
      this.state.contactItems.push(<ContactItem key="Rick" login="typeofweb3" name="Rick" department="QA" />);
      this.setState({ contactItems: this.state.contactItems });
   };
}

问题在于,即使状态发生了变化,组件也没有得到更新(我在console.log中可以看到contactItems数组正在获取新元素)。 .push()存在问题,因为如果只是将setState更改为

this.setState({ contactItems: ["something"]});

然后它可以正常工作。

2 个答案:

答案 0 :(得分:0)

我不完全知道为什么,但这有效:

class ContactsList extends Component {
   constructor(props) {
      super(props);
      this.state = {
         contactItems: [
            <ContactItem key="Lena" login="typeofweb1" name="Lena" department="JavaScript Developer" border="0" />,
            <ContactItem key="Brian" login="typeofweb2" name="Brian" department="Human Resources" />,
            <ContactItem key="Rick" login="typeofweb3" name="Rick" department="QA" />
         ]
      };
   }

   render() {
      return (
         <ul className="list-group list-group-flush container">
            {this.state.contactItems}
            <button type="button" onClick={this.addContactItem}>
               Add
            </button>
         </ul>
      );
   }

   addContactItem = () => {
      this.setState(prevState => ({
         contactItems: prevState.contactItems.concat([<ContactItem key="Rick" login="typeofweb3" name="Rick" department="QA" />])
      }));
   };
}

有人可以向我解释以下代码为何有效而前面的代码无效吗?

答案 1 :(得分:-1)

您不应在react中改变状态。您可以这样使用:

<template>
  <Page class="page">

   <StackLayout class="hello-world">
     <Button @tap="scan" text="Scan a product"/>
   </StackLayout>

  </Page>
</template>

<script>
const BarcodeScanner = require("nativescript- 
barcodescanner").BarcodeScanner;
import Display from "./Display";
export default {
data() {
  return {
    text: ""
  };
},
methods: {
scan: function() {
  var barcodescanner = new BarcodeScanner();
  barcodescanner
    .scan({
      // formats: "QR_CODE,PDF_417", // Pass in of you want to restrict scanning to certain types
      cancelLabel: "EXIT. Also, try the volume buttons!", // iOS only, default 'Close'
      cancelLabelBackgroundColor: "#333333", // iOS only, default '#000000' (black)
      message: "Use the volume buttons for extra light", // Android only, default is 'Place a barcode inside the viewfinder rectangle to scan it.'
      showFlipCameraButton: true, // default false
      preferFrontCamera: false, // default false
      showTorchButton: true, // default false
      beepOnScan: true, // Play or Suppress beep on scan (default true)
      torchOn: false, // launch with the flashlight on (default false)
      closeCallback: function() {
        console.log("Scanner closed");
      }, // invoked when the scanner was closed (success or abort)
      resultDisplayDuration: 500, // Android only, default 1500 (ms), set to 0 to disable echoing the scanned text
      // orientation: "landscape", // Android only, optionally lock the orientation to either "portrait" or "landscape"
      openSettingsIfPermissionWasPreviouslyDenied: true // On iOS you can send the user to the settings app if access was previously denied
    })
    .then(
      function(result) {
        console.log("Scan format : " + result.format);
        console.log("Scan text :   " + result.text);
        this.text = result.text;

      },
      function(error) {
        console.log("No scan: " + error);
      }
    );
  }
}
};
</script>
相关问题