我的代码中包含以下组件:
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"]});
然后它可以正常工作。
答案 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>