空数组上的“无法读取未定义的属性‘长度’”

时间:2021-07-15 21:48:49

标签: javascript reactjs

嗨,我是 Node/React 的新手,我正在创建一个学习项目。它是将自由职业者与非营利公司联系起来的平台。用户(自由职业者)查看公司列表,然后单击按钮连接到公司。单击此按钮后,用户将将该公司添加为数据库中的关系。这工作正常。

现在我正在尝试创建一个页面,用户可以在其中查看他们的所有联系人(与他们建立联系的公司)。下面的解决方案有效,但前提是用户至少有一个连接。否则,我会收到错误 Cannot read property 'length' of undefined

为了确定要呈现哪个 JSX,我使用了条件来查看用户是否有连接。如果没有,我想显示“你没有联系”。我通过检查 if (!companies.length) 然后显示“你没有连接”来做到这一点。 companies 在状态中设置为空数组。我不明白为什么它是未定义的。即使用户没有连接,companies 仍然是一个空数组。那么为什么 companies.length 会返回这个错误?如何改进此代码以避免此问题?

function UserConnections() {
  const { currentUser } = useContext(UserContext);
  const connections = currentUser.connections;
  const [companies, setCompanies] = useState([]);

  useEffect(() => {
    const comps = connections.map((c) => VolunteerApi.getCurrentCompany(c));
    Promise.all(comps).then((comps => setCompanies(comps)));
  }, [connections]);

  if (!companies.length) {
    return (
      <div>
        <p>You have no connections</p>
      </div>
    )
  } else {
    return (
      <div>
        {companies.map(c => (
          <CompanyCard
            key={c.companyHandle}
            companyHandle={c.companyHandle}
            companyName={c.companyName}
            country={c.country}
            numEmployees={c.numEmployees}
            shortDescription={c.shortDescription}
          />
        ))}
      </div>
    );
  }
};

编辑:抱歉,我应该包括错误是从不同的组件(UserLoginForm)抛出的。当没有连接的用户登录时会抛出这个错误。 但是在UserConnections组件(上面的代码)中,如果我将if (!companies.length)更改为if (!companies),用户可以正常登录,但UserConnections不会呈现什么都没有。这就是为什么我确定错误是指 UserConnections 组件中的 companies.length

无论用户是否有连接,UserLoginForm 组件一直工作正常,所以我认为错误不是来自这里。

用户登录表单

function UserLoginForm({ loginUser }) {

  const [formData, setFormData] = useState({
    username: "",
    password: "",
  });
  const [formErrors, setFormErrors] = useState([]);
  const history = useHistory();

  // Handle form submission 
  async function handleSubmit(evt) {
    evt.preventDefault();
    let results = await loginUser(formData);
    if (results.success) {
      history.push("/companies");
    } else {
      setFormErrors(results.errors);
    }
  }

  // Handle change function 
  function handleChange(evt) {
    const { name, value } = evt.target;
    setFormData(d => ({ ...d, [name]: value }));
  }

  return (
    <div>
      <div>
        <h1>User Login Form</h1>
        <div>
          <form onSubmit={handleSubmit}>
            <div>
              <input
                name="username"
                className="form-control"
                placeholder="Username"
                value={formData.username}
                onChange={handleChange}
                required
              />
            </div>
            <div>
              <input
                name="password"
                className="form-control"
                placeholder="Password"
                type="password"
                value={formData.password}
                onChange={handleChange}
                required
              />
            </div>

            {formErrors.length
              ? <Alert type="danger" message={formErrors} />
              : null
            }

            <button className="btn btn-lg btn-primary my-3">
              Submit
            </button>
          </form>
        </div>
      </div>
    </div>

  );
};

编辑 2:此线程中提供的解决方案实际上解决了问题。由于来自另一个组件的不同问题,错误消息一直存在。

2 个答案:

答案 0 :(得分:2)

改变这个:

{companies.map(c => (...)}

为此:

{companies && companies.map(c => (...)}

还有这个:

if (!companies.length) {

为此:

if (!companies || companies.length === 0) {

这将在运行映射操作或检查长度之前检查空值。

答案 1 :(得分:0)

<块引用>

即使用户没有联系,公司仍然是一个空数组。那么为什么 company.length 会返回这个错误?

您认为 companies 是空数组的假设是不正确的。不知何故,它被设置为 undefined。您可以通过这样做来防止这种情况

  if (!companies || companies.length == 0) {

或确保 companies 始终设置为数组。