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

在SPFx WebPart中使用React useState报错求助

问题分析与解决方法

你的代码报错核心原因是违反了React Hook的使用规则:

  • useState 是React Hook,只能在函数组件或自定义Hook的顶层作用域中调用,不能放在类组件外部,也不能在类组件的任何方法(包括构造函数)里使用。
  • 你把useState定义在类组件外面,同时在类的构造函数里调用setNameOnCard,完全不符合Hook的使用逻辑,导致WebPart加载时出错。

下面给你两种可行的修正方案:


方案一:改用函数组件(推荐,符合React 17+最佳实践)

把类组件改成函数组件,在组件内部正确使用useState:

import * as React from 'react';
import styles from './PaymentForm.module.scss';
import type { IPaymentFormProps } from './IPaymentFormProps';
import { escape } from '@microsoft/sp-lodash-subset';

export default function PaymentForm(props: IPaymentFormProps): React.ReactElement<IPaymentFormProps> {
  // 在函数组件顶层调用useState
  const [nameOnCard, setNameOnCard] = React.useState("james");

  const {
    description,
    isDarkTheme,
    environmentMessage,
    hasTeamsContext,
    userDisplayName
  } = props;

  return (
    <section className={`${styles.paymentForm} ${hasTeamsContext ? styles.teams : ''}`}>
      {nameOnCard}
      <div className={styles.welcome}>
        <img 
          alt="" 
          src={isDarkTheme ? require('../assets/welcome-dark.png') : require('../assets/welcome-light.png')} 
          className={styles.welcomeImage} 
        />
        <h2>Well done, {escape(userDisplayName)}!</h2>
        <div>{environmentMessage}</div>
        <div>Web part property value: <strong>{escape(description)}</strong></div>
      </div>
      <div>
        <h3>Welcome to SharePoint Framework!</h3>
        <p>
          The SharePoint Framework (SPFx) is a extensibility model for Microsoft Viva, Microsoft Teams and SharePoint. It&#39;s the easiest way to extend Microsoft 365 with automatic Single Sign On, automatic hosting and industry standard tooling.
        </p>
        <h4>Learn more about SPFx development:</h4>
        <ul className={styles.links}>
          <li><a href="https://aka.ms/spfx" target="_blank" rel="noreferrer">SharePoint Framework Overview</a></li>
          <li><a href="https://aka.ms/spfx-yeoman-graph" target="_blank" rel="noreferrer">Use Microsoft Graph in your solution</a></li>
          <li><a href="https://aka.ms/spfx-yeoman-teams" target="_blank" rel="noreferrer">Build for Microsoft Teams using SharePoint Framework</a></li>
          <li><a href="https://aka.ms/spfx-yeoman-viva" target="_blank" rel="noreferrer">Build for Microsoft Viva Connections using SharePoint Framework</a></li>
          <li><a href="https://aka.ms/spfx-yeoman-store" target="_blank" rel="noreferrer">Publish SharePoint Framework applications to the marketplace</a></li>
          <li><a href="https://aka.ms/spfx-yeoman-api" target="_blank" rel="noreferrer">SharePoint Framework API reference</a></li>
          <li><a href="https://aka.ms/m365pnp" target="_blank" rel="noreferrer">Microsoft 365 Developer Community</a></li>
        </ul>
      </div>
    </section>
  );
}

修改说明:

  1. 把类组件改为函数组件,直接接收props参数
  2. 在函数组件的顶层作用域调用useState,初始化值为"james"
  3. 直接使用props里的属性,不需要通过this.props访问

方案二:继续使用类组件(保留原有组件形态)

如果你想继续用类组件,就用React类组件的传统state方式,不要用Hook:

import * as React from 'react';
import styles from './PaymentForm.module.scss';
import type { IPaymentFormProps } from './IPaymentFormProps';
import { escape } from '@microsoft/sp-lodash-subset';

// 定义组件的state类型
interface IPaymentFormState {
  nameOnCard: string;
}

export default class PaymentForm extends React.Component<IPaymentFormProps, IPaymentFormState> {
  constructor(props: IPaymentFormProps) {
    super(props);
    // 初始化类组件的state
    this.state = {
      nameOnCard: "james"
    };
  }

  public render(): React.ReactElement<IPaymentFormProps> {
    const {
      description,
      isDarkTheme,
      environmentMessage,
      hasTeamsContext,
      userDisplayName
    } = this.props;

    return (
      <section className={`${styles.paymentForm} ${hasTeamsContext ? styles.teams : ''}`}>
        {/* 通过this.state访问state值 */}
        {this.state.nameOnCard}
        <div className={styles.welcome}>
          <img 
            alt="" 
            src={isDarkTheme ? require('../assets/welcome-dark.png') : require('../assets/welcome-light.png')} 
            className={styles.welcomeImage} 
          />
          <h2>Well done, {escape(userDisplayName)}!</h2>
          <div>{environmentMessage}</div>
          <div>Web part property value: <strong>{escape(description)}</strong></div>
        </div>
        <div>
          <h3>Welcome to SharePoint Framework!</h3>
          <p>
            The SharePoint Framework (SPFx) is a extensibility model for Microsoft Viva, Microsoft Teams and SharePoint. It&#39;s the easiest way to extend Microsoft 365 with automatic Single Sign On, automatic hosting and industry standard tooling.
          </p>
          <h4>Learn more about SPFx development:</h4>
          <ul className={styles.links}>
            <li><a href="https://aka.ms/spfx" target="_blank" rel="noreferrer">SharePoint Framework Overview</a></li>
            <li><a href="https://aka.ms/spfx-yeoman-graph" target="_blank" rel="noreferrer">Use Microsoft Graph in your solution</a></li>
            <li><a href="https://aka.ms/spfx-yeoman-teams" target="_blank" rel="noreferrer">Build for Microsoft Teams using SharePoint Framework</a></li>
            <li><a href="https://aka.ms/spfx-yeoman-viva" target="_blank" rel="noreferrer">Build for Microsoft Viva Connections using SharePoint Framework</a></li>
            <li><a href="https://aka.ms/spfx-yeoman-store" target="_blank" rel="noreferrer">Publish SharePoint Framework applications to the marketplace</a></li>
            <li><a href="https://aka.ms/spfx-yeoman-api" target="_blank" rel="noreferrer">SharePoint Framework API reference</a></li>
            <li><a href="https://aka.ms/m365pnp" target="_blank" rel="noreferrer">Microsoft 365 Developer Community</a></li>
          </ul>
        </div>
      </section>
    );
  }
}

修改说明:

  1. 定义了组件的state类型IPaymentFormState,规范state的结构
  2. 在构造函数里通过this.state初始化值
  3. 在render里通过this.state.nameOnCard访问状态值
  4. 如果后续需要修改这个值,要用this.setState({ nameOnCard: "新值" }),不能直接修改state

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 23:07:51