reactjs - 如何在 Reactjs 中通过连接或推送方法附加结果
问题描述
如何在 Reactjs 中通过串联或 push 方法附加结果。
我已经尝试过在 Stackoverflow 上找到的大多数解决方案,但不幸的是,它并没有解决我的问题。
以下是详细信息。
通过显示数组中的数据,代码在下面可以正常工作。当我点击获取新价格时,通过 Axios Json 调用获取新价格,一切正常。
这是通过 Axios API 调用返回的 price.json 数据示例。
[{"category_id" : "101", "status":"1", "category_price":"900"}]
现在。这是我想要实现的目标,我希望每次用户点击获取新价格时,让检索到的价格附加到已经存在的结果中。
我知道这是push()或concat()函数的工作
我努力了
const data=this.state.data.concat(response.data);
或者
const newData = this.state.data.concat.map(store => {
但它显示concat.map 错误
这是代码
import React, { Component, Fragment } from "react";
import { render } from "react-dom";
import axios from 'axios';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
loading: false,
commenta: ''
};
}
componentDidMount() {
this.setState({
data: [{
"provision_id":"1",
"provision":"Milk",
"category":[{"category_id":"1", "category_price":"100 USD" }, {"category_id":"2", "category_price":"200 USD" },
{"category_id":"3", "category_price":"300 USD" }]
}],
});
}
// Get New Price of Milk and concatenate it
handleNewPrice(pro_id) {
alert(pro_id);
const product = {
pro_id: pro_id};
axios
.get("http://localhost/price.json", { product })
.then(response => {
/*commented below is what I have tried */
//const data=this.state.data.concat(response.data);
//const newData = this.state.data.concat.map(store => {
const newData = this.state.data.map(store => {
if (store.provision_id !== pro_id) return store;
return {
..store,
category_new: [{
...store.category_new,
category_price_new: response.data[0].category_price,
category_id_new: response.data[0].category_id
}]
};
/* Not applicable
return {
...store,
category_new: store.category.map(
category => {
if (category.category_id !== pro_id) return category;
if (category.category_id === pro_id) {
return {
...store.category_new,
category_price_new: response.data[0].category_price,
category_id_new: response.data[0].category_id
}
}
}
)
}
*/
});
this.setState(state => ({
data: newData
}));
console.log(response.data[0].category_price);
})
.catch(error => {
console.log(error);
});
}
render() {
return (
<span>
<label>
<ul>
<h1>Provision Store</h1> <br />
{this.state.data.map((store) => {
return (
<div key={store.provision_id}>
<div>
<b> Product: </b>{store.provision}
</div>
<br />
{store.category && store.category.map((cat) => {
return (
<div key={cat.category_id}>
<div>
<b>Prices:</b> {cat.category_price}
<br />
</div>
</div>
)
})}
{store.category_new && store.category_new.map((cat1) => {
return (
<div key={cat1.category_id_new}>
<div><b>New Prices:</b> {cat1.category_price_new} ----- {cat1.category_id_new}
</div>
</div>
)
})}
<input
type="button"
value="Get New Prices and Concatenate"
onClick={() => this.handleNewPrice(store.provision_id)}
/>
</div>
)
}
)}
</ul>
</label>
</span>
);
}
}
更新的代码部分
我已经尝试了三个 Stackoverflow 资深工程师提供的所有三种解决方案,但似乎只有一个可以部分工作,我仍然需要帮助
如果我通过Concat()函数实现下面的代码,然后第一次点击获取价格按钮,新价格将显示为红色。
如果然后第二次,第三次点击获取价格按钮,以此类推,而不是另一个新价格来显示/附加,它将替换/替换已经存在的红色新价格
const data= this.state.data;
data.concat([...response.data]);
如果我通过Push()函数实现下面的代码,然后第一次单击获取价格按钮,新价格将显示为红色以及一个未知的单击按钮。
如果然后第二次点击获取价格按钮,第三次等等,另一个新价格以红色显示/附加,以及另外三个我不知道它来自哪里的点击按钮
const data= this.state.data;
data.push([...response.data]);
请我需要更多帮助
以下是到目前为止的代码
import React, { Component, Fragment } from "react";
import { render } from "react-dom";
import axios from 'axios';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
loading: false,
commenta: ''
};
}
componentDidMount() {
this.setState({
data: [{
"provision_id":"1",
"provision":"Milk",
"category":[{"category_id":"1", "category_price":"100 USD" }, {"category_id":"2", "category_price":"200 USD" },
{"category_id":"3", "category_price":"300 USD" }]
}],
});
}
// Get New Price of Milk and concatenate it
handleNewPrice(pro_id) {
alert(pro_id);
const product = {
pro_id: pro_id};
axios
.get("http://localhost/price.json", { product })
.then(response => {
/* Concat function */
const data= this.state.data;
data.concat([...response.data]);
/* push function */
//const data= this.state.data;
//data.push([...response.data]);
const newData = this.state.data.map(store => {
if (store.provision_id !== pro_id) return store;
return {
...store,
category_new: [{
...store.category_new,
category_price_new: response.data[0].category_price,
category_id_new: response.data[0].category_id
}]
};
});
this.setState(state => ({data: newData}));
console.log(response.data[0].category_price);
})
.catch(error => {
console.log(error);
});
}
render() {
return (
<span>
<label>
<ul>
<h1>Provision Store</h1> <br />
{this.state.data.map((store) => {
return (
<div key={store.provision_id}>
<div>
<b> Product: </b>{store.provision}
</div>
<br />
{store.category && store.category.map((cat) => {
return (
<div key={cat.category_id}>
<div>
<b>Prices:</b> {cat.category_price}
<br />
</div>
</div>
)
})}
{store.category_new && store.category_new.map((cat1) => {
return (
<div key={cat1.category_id_new}>
<div><b style={{color: 'red'}}>New Prices:</b> {cat1.category_price_new} ----- (Price ID: {cat1.category_id_new})
</div>
</div>
)
})}
<input
type="button"
value="Get New Prices and Concatenate"
onClick={() => this.handleNewPrice(store.provision_id)}
/>
</div>
)
}
)}
</ul>
</label>
</span>
);
}
}
更新了第 2 节:按照 Stackoverflow 工程师 – Umair Farooq 的要求,API Hits 之前的初始数据
感谢 Umair 爵士,请看下面的截图。第一个屏幕截图显示 API 调用之前数据的显示方式 API 调用 之前的屏幕截图
正如您在屏幕截图中看到的那样,我们现在有2 个产品 Milk 和 Sugar,我们希望为每个产品获得新价格并将结果附加到 View
第二个屏幕截图显示了通过单击获取新价格按钮在 API 调用之后数据如何显示。
正如你在第二张截图中看到的,我点击了获取价格按钮并出现了新价格,如果我第二次点击它,我需要看到更多的新价格结果。也就是说,每次根据每种产品单击按钮时,我都需要看到更多的新价格。
我的问题是,仅在通过 API 调用第一次单击按钮时才附加新价格,但在第二次或后续单击时不会附加更多结果,这就是需要实现 concat() 或 push() 函数的地方
请您运行这个angularjs代码,看看每次单击按钮时如何附加新价格
对于 angularjs。
这是old_data.json文件
[
{"id":"1", "cat_price":"100 usd"},
{"id":"2", "cat_price":"200 usd"}
]
这是new_data.json文件
[{"id":"10", "cat_price":"900 usd--New"}]
这是一个小的 angularjs 代码,显示每次单击“获取价格”按钮时如何附加新价格
<!doctype html>
<html>
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.6/angular.min.js"></script>
</head>
<body >
<div ng-app='myapp' ng-controller="priceCtrl">
<div>
<input type='button' id='but_save' value='Get New Price and Append' ng-click="add()" >
</div>
<div ng-repeat="pr in prices">
{{pr.cat_price}}
</div>
</div>
<!-- Script -->
<script>
var fetch = angular.module('myapp', []);
fetch.controller('priceCtrl', ['$scope', '$http', function ($scope, $http) {
// Get all records
$http({
method: 'get',
url: 'http://localhost/old_data.json',
data: {request_type:1},
}).then(function successCallback(response) {
$scope.prices = response.data;
});
// Add and get new record
$scope.add = function(){
var len = $scope.prices.length;
$http({
method: 'post',
url: 'http://localhost/new_data.json',
data: {},
}).then(function successCallback(response) {
$scope.prices.push(response.data[0]);
});
}
}]);
</script>
</body>
</html>
这是 ReactJs 的更新代码
Axios API 返回响应示例
[{"category_id" : "005", "status":"1", "category_price":"900 usd"}]
主要反应代码
import React, { Component, Fragment } from "react";
import { render } from "react-dom";
import axios from 'axios';
class Apps extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
loading: false,
commenta: ''
};
}
componentDidMount() {
this.setState({
data: [{
"provision_id":"1",
"provision":"Milk",
"category":[{"category_id":"1", "category_price":"100 USD" }, {"category_id":"2", "category_price":"200 USD" }]},
{
"provision_id":"2",
"provision":"Sugar",
"category":[{"category_id":"3", "category_price":"150 USD" }, {"category_id":"4", "category_price":"300 USD" }]},
],
});
}
// Get New Price of Milk and concatenate it
handleNewPrice(pro_id) {
alert(pro_id);
const product = {
pro_id: pro_id};
axios
.get("http://localhost/price.json", { product })
.then(response => {
const data= this.state.data;
data.concat([...response.data]);
//const data= this.state.data;
//data.push([...response.data]);
const newData = this.state.data.map(store => {
if (store.provision_id !== pro_id) return store;
return {
...store,
category_new: [{
...store.category_new,
category_price_new: response.data[0].category_price,
category_id_new: response.data[0].category_id
}]
};
});
this.setState(state => ({data: newData}));
console.log(response.data[0].category_price);
})
.catch(error => {
console.log(error);
});
}
render() {
return (
<span>
<label>
<ul>
<h1>Provision Store</h1> <br />
{this.state.data.map((store) => {
return (
<div key={store.provision_id}>
<div>
<b style={{color:'blue'}}> Product: {store.provision} </b>
</div>
<br />
{store.category && store.category.map((cat) => {
return (
<div key={cat.category_id}>
<div>
<b>Prices:</b> {cat.category_price}
<br />
</div>
</div>
)
})}
{store.category_new && store.category_new.map((cat1) => {
return (
<div key={cat1.category_id_new}>
<div><b style={{color: 'red'}}>New Prices:</b> {cat1.category_price_new} ----- (Price ID: {cat1.category_id_new})
</div>
</div>
)
})}
<input
type="button"
value="Get New Prices and Concatenate"
onClick={() => this.handleNewPrice(store.provision_id)}
/>
<br />
</div>
)
}
)}
</ul>
</label>
</span>
);
}
}
解决方案
你应该做这样的事情
var newPriceobj = Object.assign({}, ...this.state.data); // This will create a fresh object //
var newPriceobjArray = Object.keys(newPriceobj).map(i => newPriceobj[i]);
newPriceobjArray.push(response.data);
this.setState({data:newPriceobjArray});
注意:不要直接改变状态,这可能会导致不可预知的情况
改变:
this.state.data.concat(response.data);
至:
var newPriceobj = Object.assign({}, ...this.state.data);
然后使用newPriceobj
.
推荐阅读
- c# - 基于“System.Security.Principal”的 c# 用户身份验证是否适用于 ADFS 和 Azure Active Directory?
- python - Numpy .eig 返回矩阵行排列
- python-3.x - 如何将模块导入为 Python 字典?
- macos - 使用 MacOS 在 Flutter 中复制 SelectableText
- javascript - 有办法只将部分字符串对象保存到异步存储中吗?
- c# - 在列表视图中显示反序列化列表的项目
- javascript - 我对此完全感到困惑,因为 else if 语句似乎破坏了程序?
- python - 当询问麦克风权限时,selenium webdriver 无法单击允许
- python - django测试客户端CRUD API,单元测试
- php - 使用 PhpSpreadsheet 表读取文件越界错误