如何在 ReactJS 中映射对象
How to map object in ReactJS
我有 mainPrice 对象:
client_type: "individual"
large_car: {100: "3", 200: "2.5"}
medium_car: {100: "3", 200: "2.5"}
small_car: {100: "2.5", 200: "2.5"}
x_large_car: {100: "3", 200: "2.5"}
xx_large_car: {100: "3", 200: "2.5"}
我想要做的是在输入框中显示每种类型的汽车。所以基本上我正在尝试映射它。例如 small_car:
<td>
{Object.keys(mainPrice.small_car).map((key) => (
<tr>
<label>{key} miles: </label>
<InputPrice
mainPricePosts={mainPrice.small_car[key]}
handleChange={handleChange}
/>
</tr>
))}
</td>
但我得到一个错误 TypeError: 无法将 undefined 或 null 转换为对象 但我不明白这个错误的原因。你能看看吗?
编辑:所以很多人说问题不在于地图,这就是为什么我想解释更多关于代码的原因。因此,在我的父组件上,我调用 API 来获取数据,并使用该数据设置 MainPrice。最后就是这个对象:
client_type: "individual"
large_car: {100: "3", 200: "2.5"}
medium_car: {100: "3", 200: "2.5"}
small_car: {100: "2.5", 200: "2.5"}
x_large_car: {100: "3", 200: "2.5"}
xx_large_car: {100: "3", 200: "2.5"}
因此,我将此数据作为 props 发送到当前组件,在该组件中我尝试将此数据显示到文本框中。
所以这里是组件:
const PricePostsIndividual = ({ mainPrice }) => {
console.log({ mainPrice })
return (
<>
<tbody className="price_coefficient">
<td>
{/* {Object.keys(mainPrice.small_car).map((key) => (
<tr>
<label>{key} miles: </label>
<InputPrice
mainPricePosts={mainPrice.small_car[key]}
handleChange={handleChange}
/>
</tr>
))} */}
</td>
</tbody>
</>
);
};
export default PricePostsIndividual;
如您所见,我在 of 的旁边评论过,在这种情况下 mainProce 即将到来。
和父组件:
export default function PriceCoefficient() {
const [mainPrice, setMainPrice] = useState({})
const [loading, setLoading] = useState(false);
const [error, setError] = useState(false);
useEffect(() => {
const fetchPosts = async () => {
try {
setLoading(true);
const res = await Axios({
method: "POST",
url: `url`,
headers: {
"cache-Control": "no-cache",
"content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
},
});
if (res.status === 200) {
setMainPrice(res.data.main_price);
}
setLoading(false);
} catch (err) {
setError(err.message);
setLoading(false);
}
};
fetchPosts();
}, []);
return (
<>
<PanelHeader size="sm" />
<div className="content">
<Row>
<Col xs={12}>
<Card>
<CardBody>
<h4>Main Prices</h4>
<Table responsive>
<thead className="text-primary">
<tr>
<th>Small Cars</th>
</tr>
</thead>
<PricePostsMainPrice
mainPrice={mainPrice}
loading={loading}
error={error}
/>
</Table>
</CardBody>
</Card>
</Col>
</Row>
</div>
</>
);
}
谢谢...
<td>
{Object.keys(mainPrice.small_car).forEach((item) => (
<tr>
<label>{item} miles: </label>
<InputPrice
mainPricePosts={item}
handleChange={handleChange}
/>
</tr>
))}
</td>
您不应在此处使用地图,因为您不需要创建另一个对象。你只需要 iterate.So,最好使用 foreach。
检查项目对象,看看你需要什么。
我觉得不是对象的问题,可能是其他问题导致的错误。
let object = {
client_type: "individual",
large_car: { 100: "3", 200: "2.5" },
medium_car: { 100: "3", 200: "2.5" },
small_car: { 100: "2.5", 200: "2.5" },
x_large_car: { 100: "3", 200: "2.5" },
xx_large_car: { 100: "3", 200: "2.5" }
};
class App extends React.Component {
render() {
return (
<div>
{Object.keys(object.small_car).map((key) => (
<tr>
<label>{key} miles: </label>
<input value={object.small_car[key]} />
</tr>
))}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("container"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="container"></div>
<td>
parts.map((part, partIndex) => {
<tr>
<label>{key} miles: </label>
<InputPrice
mainPricePosts={part.small_car}
handleChange={handleChange}
/>
</tr>
))}
</td>
问题
这里的问题是您的初始 mainPrice
状态是空对象 ({}
)。
const [mainPrice, setMainPrice] = useState({});
这似乎最终会传递到 PricePostsIndividual
,当您尝试 Object.keys(mainPrice.small_car)
时会抛出 Cannot convert undefined or null to object
错误。
const mainPrice = {};
try {
Object.keys(mainPrice.small_car);
console.log('no error thrown');
} catch(error) {
console.error(error.message);
}
解决方案
使用一些 null 检查(保护子句)或可选链接,或为嵌套状态提供回退值(Nullish Coalescing)以映射到 JSX。
const mainPrice = {};
try {
// Null check/guard clause
mainPrice.small_car && Object.keys(mainPrice.small_car);
// Nullish Coalescing to provide fallback
Object.keys(mainPrice.small_car ?? {});
console.log('no error thrown');
} catch(error) {
console.error(error.message);
}
我建议如下:
const PricePostsIndividual = ({ mainPrice = {} }) => { // provide initial value
return (
<>
<tbody className="price_coefficient">
<td>
// Use Object.entries to get array of key-value pairs
// provide fallback for mainPrice.small_car
{Object.entries(mainPrice.small_car ?? {}).map(([key, value]) => (
<tr>
<label>{key} miles: </label> // render key
<InputPrice
mainPricePosts={value} // render value
handleChange={handleChange} // ensure this handler is defined!!
/>
</tr>
))}
</td>
</tbody>
</>
);
};
我有 mainPrice 对象:
client_type: "individual"
large_car: {100: "3", 200: "2.5"}
medium_car: {100: "3", 200: "2.5"}
small_car: {100: "2.5", 200: "2.5"}
x_large_car: {100: "3", 200: "2.5"}
xx_large_car: {100: "3", 200: "2.5"}
我想要做的是在输入框中显示每种类型的汽车。所以基本上我正在尝试映射它。例如 small_car:
<td>
{Object.keys(mainPrice.small_car).map((key) => (
<tr>
<label>{key} miles: </label>
<InputPrice
mainPricePosts={mainPrice.small_car[key]}
handleChange={handleChange}
/>
</tr>
))}
</td>
但我得到一个错误 TypeError: 无法将 undefined 或 null 转换为对象 但我不明白这个错误的原因。你能看看吗?
编辑:所以很多人说问题不在于地图,这就是为什么我想解释更多关于代码的原因。因此,在我的父组件上,我调用 API 来获取数据,并使用该数据设置 MainPrice。最后就是这个对象:
client_type: "individual"
large_car: {100: "3", 200: "2.5"}
medium_car: {100: "3", 200: "2.5"}
small_car: {100: "2.5", 200: "2.5"}
x_large_car: {100: "3", 200: "2.5"}
xx_large_car: {100: "3", 200: "2.5"}
因此,我将此数据作为 props 发送到当前组件,在该组件中我尝试将此数据显示到文本框中。
所以这里是组件:
const PricePostsIndividual = ({ mainPrice }) => {
console.log({ mainPrice })
return (
<>
<tbody className="price_coefficient">
<td>
{/* {Object.keys(mainPrice.small_car).map((key) => (
<tr>
<label>{key} miles: </label>
<InputPrice
mainPricePosts={mainPrice.small_car[key]}
handleChange={handleChange}
/>
</tr>
))} */}
</td>
</tbody>
</>
);
};
export default PricePostsIndividual;
如您所见,我在 of 的旁边评论过,在这种情况下 mainProce 即将到来。
和父组件:
export default function PriceCoefficient() {
const [mainPrice, setMainPrice] = useState({})
const [loading, setLoading] = useState(false);
const [error, setError] = useState(false);
useEffect(() => {
const fetchPosts = async () => {
try {
setLoading(true);
const res = await Axios({
method: "POST",
url: `url`,
headers: {
"cache-Control": "no-cache",
"content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
},
});
if (res.status === 200) {
setMainPrice(res.data.main_price);
}
setLoading(false);
} catch (err) {
setError(err.message);
setLoading(false);
}
};
fetchPosts();
}, []);
return (
<>
<PanelHeader size="sm" />
<div className="content">
<Row>
<Col xs={12}>
<Card>
<CardBody>
<h4>Main Prices</h4>
<Table responsive>
<thead className="text-primary">
<tr>
<th>Small Cars</th>
</tr>
</thead>
<PricePostsMainPrice
mainPrice={mainPrice}
loading={loading}
error={error}
/>
</Table>
</CardBody>
</Card>
</Col>
</Row>
</div>
</>
);
}
谢谢...
<td>
{Object.keys(mainPrice.small_car).forEach((item) => (
<tr>
<label>{item} miles: </label>
<InputPrice
mainPricePosts={item}
handleChange={handleChange}
/>
</tr>
))}
</td>
您不应在此处使用地图,因为您不需要创建另一个对象。你只需要 iterate.So,最好使用 foreach。
检查项目对象,看看你需要什么。
我觉得不是对象的问题,可能是其他问题导致的错误。
let object = {
client_type: "individual",
large_car: { 100: "3", 200: "2.5" },
medium_car: { 100: "3", 200: "2.5" },
small_car: { 100: "2.5", 200: "2.5" },
x_large_car: { 100: "3", 200: "2.5" },
xx_large_car: { 100: "3", 200: "2.5" }
};
class App extends React.Component {
render() {
return (
<div>
{Object.keys(object.small_car).map((key) => (
<tr>
<label>{key} miles: </label>
<input value={object.small_car[key]} />
</tr>
))}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("container"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="container"></div>
<td>
parts.map((part, partIndex) => {
<tr>
<label>{key} miles: </label>
<InputPrice
mainPricePosts={part.small_car}
handleChange={handleChange}
/>
</tr>
))}
</td>
问题
这里的问题是您的初始 mainPrice
状态是空对象 ({}
)。
const [mainPrice, setMainPrice] = useState({});
这似乎最终会传递到 PricePostsIndividual
,当您尝试 Object.keys(mainPrice.small_car)
时会抛出 Cannot convert undefined or null to object
错误。
const mainPrice = {};
try {
Object.keys(mainPrice.small_car);
console.log('no error thrown');
} catch(error) {
console.error(error.message);
}
解决方案
使用一些 null 检查(保护子句)或可选链接,或为嵌套状态提供回退值(Nullish Coalescing)以映射到 JSX。
const mainPrice = {};
try {
// Null check/guard clause
mainPrice.small_car && Object.keys(mainPrice.small_car);
// Nullish Coalescing to provide fallback
Object.keys(mainPrice.small_car ?? {});
console.log('no error thrown');
} catch(error) {
console.error(error.message);
}
我建议如下:
const PricePostsIndividual = ({ mainPrice = {} }) => { // provide initial value
return (
<>
<tbody className="price_coefficient">
<td>
// Use Object.entries to get array of key-value pairs
// provide fallback for mainPrice.small_car
{Object.entries(mainPrice.small_car ?? {}).map(([key, value]) => (
<tr>
<label>{key} miles: </label> // render key
<InputPrice
mainPricePosts={value} // render value
handleChange={handleChange} // ensure this handler is defined!!
/>
</tr>
))}
</td>
</tbody>
</>
);
};