使用 refs 将 React class 转换为功能组件

converting react class to functional component with refs

我正在尝试使用 stackblitz file 中的 class 示例并将其转换为功能组件。

我不明白 ref 是如何工作的,或者 onTyping 函数中使用的 eventargs 来自哪里。任何人都可以解释它们的定义位置以及我如何将其转换为功能组件吗?

import { render } from 'react-dom';
import './index.css';
import * as React from 'react';
import { AutoCompleteComponent } from '@syncfusion/ej2-react-dropdowns';
import { SampleBase } from './sample-base';

import * as data from './dataSource.json';
export class Default extends SampleBase {
    constructor() {
        super(...arguments);
        this.temp = 'sportsData';
        // define the array of string
        this.sportsData = data[this.temp];
    }
    onTyping(args) {
console.log(event.target.value);
    }
    render() {
        return (<div id='combodefault' className='control-pane'>
        <div className='control-section'>
        <div className='col-lg-12 control-wrappers'>
            <div id='default'>
            <AutoCompleteComponent id="games" dataSource={this.sportsData} ref={(AutoComplete) => { this.listObj = AutoComplete; }} placeholder="e.g. Basketball" actionBegin={this.onTyping}/>
            </div>
        </div>
        </div>
        
    </div>);
    }
}

render(<Default />, document.getElementById('sample'));

构造函数中的任何内容都需要转换为 useState:

    this.temp = 'sportsData';
    // define the array of string
    this.sportsData = data[this.temp];

变成:

const[temp, setTemp] = useState('sportsData');
const[sportsData, setSportsData] = useState(data[temp]);

setTemp 和 setSportsData 是分别用于设置状态变量 temp 和 sportsData 的函数。例如,以下将 temp 设置为 'NFSSportsData'.

setTemp('NFLSportsData');

至于ref,可以使用钩子useRef.

const listObj = useRef(null);

对于组件生命周期方法componentDidMount,可以使用如下约定。

useEffect(()=>{
// your code
}, [])

空括号[]表示仅对运行组件挂载时的代码一次。如果你想编码监听一个状态变量,并且每次变量变化时 运行s,你可以执行以下操作:

useEffect(()=>{
// your code
}, [sportsData])

每次状态变量 sportsData 发生变化时,上述代码都会 运行。

我认为没有办法像您使用 SampleBase 那样扩展功能组件。查看SampleBase class,它只是运行在生命周期组件componentDidMount 中调用一个函数。您可以执行以下操作:

rendereComplete() {
    /**custom render complete function */
}
useEffect(()=>{
    setTimeout(() => {
    this.rendereComplete();
},[]);

要领结就全部在一起了,你有这样的东西:

import './index.css';
import * as React from 'react';
import { AutoCompleteComponent } from '@syncfusion/ej2-react-dropdowns';
import * as data from './dataSource.json';

export const Default = ()=> {
  const [temp, setTemp] = React.useState('sportsData');
  const [sportsData, setSportsData] = useState(data[this.temp]);
  const listObj = useRef(null);

  const onTyping = (args)=>{
    console.log('arg =', args);
  }
  
  const rendereComplete() {
        /**custom render complete function */
    }
  useEffect(()=>{
        setTimeout(() => {
        rendereComplete();
  },[]);
  return (<div id='combodefault' className='control-pane'>
  <div className='control-section'>
  <div className='col-lg-12 control-wrappers'>
      <div id='default'>
      <AutoCompleteComponent id="games" dataSource={sportsData} ref={(AutoComplete) => { listObj = AutoComplete; }} placeholder="e.g. Basketball" actionBegin={onTyping}/>
      </div>
  </div>
  </div>
  
</div>);
}