无法在对象被定义时显示对象属性(React)

huangapple go评论82阅读模式
英文:

Unable to display object properties when the object seems to be defined (React)

问题

我在一个MERN堆栈应用中有一些代码,用户可以在搜索栏中输入另一个用户的姓名,网页将返回他们搜索的用户的其他属性。

例如,如果我在搜索栏中搜索“John Doe”,前端应返回如下内容:

姓名:John Doe
年龄:30
性别:男


这是我用于处理此功能的React组件的代码:

import React, { useState, useEffect } from "react";
import axios from "axios";
import "../../styles/styles.css";

function SearchUser() {
const [user, setUser] = useState({});
const [searchQuery, setSearchQuery] = useState("");
const [formError, setFormError] = useState(false);

async function getUsers(query) {
const response = await axios.get(http://localhost:5000/auth/userSearch?fullName=${query});
setUser(response.data);
}

const handleSubmit = async (e) => {
e.preventDefault();

if (!searchQuery) {
  setFormError(true);
  return;
}

setFormError(false);
getUsers(searchQuery);

};

useEffect(() => {
console.log(user);
}, [user]);

return (

搜索用户

<input
type="text"
placeholder="在此输入用户的全名"
onChange={(e) => {
setSearchQuery(e.target.value);
}}
value={searchQuery}
/>
{formError && !searchQuery && (

这是一个必填字段

)}


    {user.fullName && (
      <div>
        <p>姓名:{user.fullName}</p>
        <p>年龄:{user.age}</p>
        <p>性别:{user.sex}</p>
      </div>
    )}
  </div>
</div>

);
}

export default SearchUser;


**我的问题:**

经过调试和一些控制台日志记录,似乎user.fullName/user.age/user.email都是未定义的。然而,在这个控制台日志中:

useEffect(() => {
console.log("effect[user]:", JSON.stringify(user));
}, [user]);


当我在搜索栏中输入“John Doe”时,浏览器控制台中返回了一个用户对象:

effect[user]: {"user":{"_id":"63eea67c0316be96ebf799f0","email":"johndoe@example.com","passwordHash":"DU7fwnIlucrwT7R","fullName":"John Doe","age":"30","sex":"male","__v":0}}


我怀疑渲染过程中存在一些问题,但由于我对React还不够熟悉,不确定接下来该怎么办。任何帮助将不胜感激。
英文:

I have some code in a MERN stack app where users can enter another user's name into a search bar, and the webpage will return other properties of the user whose name they searched up.

For example, if I search up "John Doe" in the search bar, it should return something like this in the front end:

Name: John Doe
Age: 30
Sex: Male

Here is the code for the React component I made to handle this:

import React, { useState, useEffect } from &quot;react&quot;;
import axios from &quot;axios&quot;;
import &quot;../../styles/styles.css&quot;;

function SearchUser() {
  const [user, setUser] = useState({});
  const [searchQuery, setSearchQuery] = useState(&quot;&quot;);
  const [formError, setFormError] = useState(false);

  async function getUsers(query) {
    const response = await axios.get(`http://localhost:5000/auth/userSearch?fullName=${query}`);
    setUser(response.data);
  }

  const handleSubmit = async (e) =&gt; {
    e.preventDefault();

    if (!searchQuery) {
      setFormError(true);
      return;
    }

    setFormError(false);
    getUsers(searchQuery);
  };

  useEffect(() =&gt; {
    console.log(user);
  }, [user]);

  return (
    &lt;div className=&quot;container&quot;&gt;
      &lt;div className=&quot;create-profile-border&quot;&gt;
        &lt;h1&gt;Search a user&lt;/h1&gt;
        &lt;form onSubmit={handleSubmit}&gt;
          &lt;div&gt;
            &lt;input
              type=&quot;text&quot;
              placeholder=&quot;Enter a user&#39;s full name here&quot;
              onChange={(e) =&gt; {
                setSearchQuery(e.target.value);
              }}
              value={searchQuery}
            /&gt;
            {formError &amp;&amp; !searchQuery &amp;&amp; (
              &lt;p className=&quot;error-message&quot;&gt;This is a required field&lt;/p&gt;
            )}
          &lt;/div&gt;
          &lt;button className=&quot;create-profile-button&quot; type=&quot;submit&quot;&gt;
            Search
          &lt;/button&gt;
        &lt;/form&gt;

        {user.fullName &gt; 0 &amp;&amp; (
          &lt;div&gt;
            &lt;p&gt;Name: {user.fullName}&lt;/p&gt;
            &lt;p&gt;Age: {user.age}&lt;/p&gt;
            &lt;p&gt;Sex: {user.sex}&lt;/p&gt;
          &lt;/div&gt;
        )}
      &lt;/div&gt;
    &lt;/div&gt;
  );
}


export default SearchUser;

I have checked and confirmed that the backend code is working properly, the issue purely lies in the frontend.

The Issue I have:

After debugging and some console logging, it seems that user.fullName/user.age/user.email are all undefined. However, in this console log:

useEffect(() =&gt; {
    console.log(&quot;effect[user]:&quot;, JSON.stringify(user));
  }, [user]);

I get back a user object in the browser console when I type "John Doe" in the search bar:

effect[user]: {&quot;user&quot;:{&quot;_id&quot;:&quot;63eea67c0316be96ebf799f0&quot;,&quot;email&quot;:&quot;johndoe@example.com&quot;,&quot;passwordHash&quot;:&quot;DU7fwnIlucrwT7R&quot;,&quot;fullName&quot;:&quot;John Doe&quot;,&quot;age&quot;:&quot;30&quot;,&quot;sex&quot;:&quot;male&quot;,&quot;__v&quot;:0}}

I suspect there's some funny business with the rendering but as I'm still inexperienced with React, I'm not sure where to go from here. Any help would be greatly appreciated.

答案1

得分: 1

我订阅了来自 Phil 的所有建议。然而,在查看了你控制台的日志后,我认为你的数据是以用户的形式返回的。因此,你应该能够通过将 user 设置为 response.data.user 来获取数据。

async function getUsers(query) {
    const response = await axios.get(`http://localhost:5000/auth/userSearch?fullName=${query}`);
    setUser(response.data.user);
}

或者

const getUsers = async (fullName) => {
    setUser(
        (
            await axios.get("/auth/userSearch", {
                baseURL: "http://localhost:5000/", // 更好的做法是使用你的 .env 文件
                params: { fullName },
            })
        ).data.user
    );
};
英文:

I subscribe to all the suggestions from phil. However, after looking at the log from your console, I think your data is returned as a user. so you should be able to get the data by setting user to response.data.user

async function getUsers(query) {
    const response = await axios.get(`http://localhost:5000/auth/userSearch?fullName=${query}`);
    setUser(response.data.user);
  }

or

const getUsers = async (fullName) =&gt; {
  setUser(
    (
      await axios.get(&quot;/auth/userSearch&quot;, {
        baseURL: &quot;http://localhost:5000/&quot;, // even better, use your .env file
        params: { fullName },
      })
    ).data.user
  );
};

答案2

得分: 0

你的主要问题在于尝试将字符串属性 user.fullName 与数字 0 进行比较。除非你的字符串是纯数字,否则 user.fullName > 0 将始终为 false

而不是将 user 初始化为空对象,尝试将其初始值设为 null。然后你可以更容易地测试它是否有值或没有...

const [user, setUser] = useState(null);

// ...

{user && (
  <div>
    <p>姓名: {user.fullName}</p>
    <p>年龄: {user.age}</p>
    <p>性别: {user.sex}</p>
  </div>
)}

另一个改进是使用 Axios 的 params 选项来正确编码URL查询参数。

更新:在提示你调试自己的API响应之后,还似乎你的响应数据是嵌套在一个 user 属性下的。

const getUsers = async (fullName) => {
  setUser(
    (
      await axios.get("/auth/userSearch", {
        baseURL: "http://localhost:5000/", // 更好的做法是使用你的 .env 文件
        params: { fullName },
      })
    ).data.user // 提取 `user` 属性
  );
};

无法在对象被定义时显示对象属性(React)

英文:

Your main issue is trying to compare the string property user.fullName to numeric 0. Unless your string is purely numeric, user.fullName &gt; 0 will always be false.

Instead of initialising user to be an empty object, try starting it with null. Then you can more easily test if it has a value or not...

const [user, setUser] = useState(null);

// ...

{user &amp;&amp; (
  &lt;div&gt;
    &lt;p&gt;Name: {user.fullName}&lt;/p&gt;
    &lt;p&gt;Age: {user.age}&lt;/p&gt;
    &lt;p&gt;Sex: {user.sex}&lt;/p&gt;
  &lt;/div&gt;
)}

Another improvement you can make is to employ Axios' params option to correctly encode URL query parameters.

Update: after prompting you to debug your own API response, it also seems your response data is nested under a user property

const getUsers = async (fullName) =&gt; {
  setUser(
    (
      await axios.get(&quot;/auth/userSearch&quot;, {
        baseURL: &quot;http://localhost:5000/&quot;, // even better, use your .env file
        params: { fullName },
      })
    ).data.user // &#128072; extract the `user` property
  );
};

无法在对象被定义时显示对象属性(React)

答案3

得分: 0

{
  user: { _id: &quot;...&quot;, email: &quot;...&quot;, passwordHash: &quot;...&quot;, fullName: &quot;...&quot; },
  _id: &quot;63eea67c0316be96ebf799f0&quot;
  age: &quot;30&quot;
}
英文:

Can you share the full JSON response from your API? I'm asking because what you pasted seems to imply the response looks something like this:

{
  user: { _id: &quot;...&quot;, email: &quot;...&quot;, passwordHash: &quot;...&quot; },
  _id: &quot;63eea67c0316be96ebf799f0&quot;
  fullName: &quot;John Doe&quot;
​​  age: &quot;30&quot;
}

Said another way... Based on your paste, the data.user object does not contain the fullName property, but rather data.fullName does.

huangapple
  • 本文由 发表于 2023年2月18日 04:28:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/75488997.html
  • axios
  • javascript
  • react-hooks
  • reactjs

如何在 :?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定