如何在 ReactJS 中映射对象
2021-07-06
1405
我有 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:无法将未定义或 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"}
因此,我将这些数据作为道具发送到当前组件,然后尝试将这些数据显示到文本框中。
所以这里是组件:
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;
正如您所见,我评论了 isnide 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>
</>
);
}
谢谢...
3个回答
问题
这里的问题是,您的初始
mainPrice
状态是一个空对象 (
{})。
const [mainPrice, setMainPrice] = useState({});
最终,它似乎被传递到了
PricePostsIndividual
,当您尝试
Object.keys(mainPrice.small_car)
时,会抛出
无法将未定义或 null 转换为对象
错误。
const mainPrice = {};
try {
Object.keys(mainPrice.small_car);
console.log('no error thrown');
} catch(error) {
console.error(error.message);
}
解决方案
使用一些空检查(保护子句)或可选链,或为嵌套状态提供后备值(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>
</>
);
};
Drew Reese
2021-07-06
我认为问题不在于对象,也许错误是指另一个问题。
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>
rdonadono
2021-07-06
<td>
parts.map((part, partIndex) => {
<tr>
<label>{key} miles: </label>
<InputPrice
mainPricePosts={part.small_car}
handleChange={handleChange}
/>
</tr>
))}
</td>
Shahzad Khan
2021-07-06