You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React展示API返回JSON中retDonnees嵌套对象的问题求助

解决React展示API返回的retDonnees数据问题

我看了你的代码,问题主要出在数据层级的访问和组件props传递上,还有几个小拼写错误,咱们一步步来修正:

核心问题拆解

  1. API返回的是数组结构,第一个对象里包含retEntete和retDonnees两层,但你在setState时直接把data[0]赋值给了test,导致在DisplayTest里直接访问test.constat是找不到的——它实际藏在test.retDonnees.constat里。
  2. App组件render里给DisplayTest传的recupTest根本没定义,应该传递this.state.test.retDonnees,而且得处理初始加载时数据未返回的空值情况,避免报错。
  3. DisplayTest里的按钮有拼写错误:把法语的reponse写成了英语的response,导致选项渲染不出来。

具体修改步骤

1. 修正App组件的state更新逻辑

在getTest的异步回调里,直接把API返回的retDonnees层级赋值给state的test,这样后续访问更直接:

.then(data => {
  console.log(data)
  this.setState({ test: data[0].retDonnees }); // 跳过外层,直接取retDonnees
});

然后在render里,把正确的state数据传给DisplayTest:

<DisplayTest test={this.state.test} />

2. 修复DisplayTest的拼写错误

把按钮里的test.response1、test.response3改成test.reponse1、test.reponse3:

<MDBBtn>{test.reponse1}</MDBBtn>
<MDBBtn>{test.reponse2}</MDBBtn>
<MDBBtn>{test.reponse3}</MDBBtn>
<MDBBtn>{test.reponse4}</MDBBtn>

3. 添加空值保护(推荐)

因为API请求是异步的,初始渲染时test还是初始的空对象,所以可以在DisplayTest里加个加载提示,或者用可选链避免报错:

const DisplayTest = ({test}) => {
  if (!test.constat) return <div>正在加载测试内容...</div>;
  
  return (
    // 原组件内容
  );
}

修改后的完整代码

App.js

const afficheInit = { constat: null, instruction: null }
const appInit = { appMode: "evaluation", appEtape: "init1" }
class App extends Component {
  constructor(props) {
    super(props);
    this.state = { test: afficheInit, envEntete: appInit, retEntete: null };
  }
  componentDidMount() {
    this.getTest(this.state);
  }
  getTest(param) {
    fetch("an API", {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'text/plain'
      },
      body: JSON.stringify(param),
    })
    .then(response => response.json())
    .then(data => {
      console.log(data)
      this.setState({ test: data[0].retDonnees });
    });
  }
  render() {
    const mode = "Evaluation"; // 这里假设你有定义mode变量,按需调整
    if (mode === "Evaluation") {
      return (
        <MDBCol>
          <MDBCard>
            <MDBCardImage className="img-fluid" src="https://mdbootstrap.com/img/Photos/Others/images/43.jpg" waves />
            <MDBCardBody>
              <DisplayTest test={this.state.test} />
              <GenerateTest selectTest={() => this.getTest()} />
            </MDBCardBody>
          </MDBCard>
        </MDBCol>
      );
    } else {
      return (
        <MDBCol>
          <MDBCard>
            <MDBCardImage className="img-fluid" src="https://mdbootstrap.com/img/Photos/Others/images/43.jpg" waves />
            <MDBCardBody>
              <MDBCardTitle>???</MDBCardTitle>
              <MDBCardText> Oh! </MDBCardText>
              <MDBBtn href="#">Hey !</MDBBtn>
            </MDBCardBody>
          </MDBCard>
        </MDBCol>
      );
    }
  }
}
export default App;

DisplayTest.jsx

const DisplayTest = ({test}) => {
  if (!test.constat) return <div>正在加载测试内容...</div>;
  
  return (
    <div className="DisplayTest">
      <p className='superclasse'> {test.constat} </p>
      <MDBCardTitle className= 'super'>{test.instruction}</MDBCardTitle>
      <MDBCardText> {test.question1}</MDBCardText>
      <MDBCardText> {test.question2}</MDBCardText>
      <MDBCardText> {test.question3}</MDBCardText>
      <MDBBtn>{test.reponse1}</MDBBtn>
      <MDBBtn>{test.reponse2}</MDBBtn>
      <MDBBtn>{test.reponse3}</MDBBtn>
      <MDBBtn>{test.reponse4}</MDBBtn>
    </div>
  );
}
export default DisplayTest;

进阶:用Object.keys.map动态渲染内容

如果你想让组件更灵活(比如以后增加question/reponse字段不用改代码),可以用Object.keys配合map动态渲染:

const DisplayTest = ({test}) => {
  if (!test) return <div>加载中...</div>;

  // 过滤出所有question开头的字段
  const questions = Object.entries(test).filter(([key]) => key.startsWith('question'));
  // 过滤出所有非正确答案的reponse字段
  const reponses = Object.entries(test).filter(([key]) => key.startsWith('reponse') && !key.includes('correcte'));

  return (
    <div className="DisplayTest">
      <p className='superclasse'> {test.constat} </p>
      <MDBCardTitle className= 'super'>{test.instruction}</MDBCardTitle>
      {/* 动态渲染问题 */}
      {questions.map(([key, value]) => (
        <MDBCardText key={key}>{value}</MDBCardText>
      ))}
      {/* 动态渲染选项按钮 */}
      {reponses.map(([key, value]) => (
        <MDBBtn key={key}>{value}</MDBBtn>
      ))}
    </div>
  );
}

内容的提问来源于stack exchange,提问作者Marion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 03:59:39