简体   繁体   中英

TypeScript linting error: ref does not exist on component

When trying to add a ref to my component, I am getting a linting error:

TS2339: Property 'childNavRef' does not exist on type 'Navigation'

在此处输入图片说明

How do I properly attach a reference for a typescript react component? Thanks, and you can see the code below for the component as well as the tsconfig and eslint.

navigation.tsx:

import * as React from 'react';

interface MyState {
  show: boolean;
}

export default class Navigation extends React.Component<{}, MyState> {
  public constructor() {
    super({});
    this.state = {
      show: true,
    };
    this.childNavRef = React.createRef();
  }

  public render(): React.ReactElement {
    return (
      <nav>
        {
          this.state.show
          && (
          <div ref={this.childNavRef}>
            This is a component
          </div>
          )
        }
      </nav>
    );
  }
}

tsconfig.json:

{
  "compilerOptions": {
    "outDir": "./dist/",
    "sourceMap": true,
    "noImplicitAny": true,
    "module": "es6",
    "moduleResolution": "node",
    "target": "es5",
    "jsx": "react",
    "allowJs": true,
    "baseUrl": ".",
    "paths": {
      "actions/*": ["src/app/redux/actions/*"],
    }
  }
}

.estlintrc:

module.exports = {
  env: {
    'jest/globals': true
  },
  extends: [
    'airbnb',
    'plugin:@typescript-eslint/recommended',
  ],
  globals: {
    'document': true,
    'window': true,
  },
  overrides: [
    {
      'files': ['**/*.tsx'],
      'rules': {
        'react/prop-types': 'off'
      }
    }
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    project: './tsconfig.json',
  },
  plugins: ['@typescript-eslint', 'jest'],
  rules: {
    'import/no-extraneous-dependencies': [
      'error',
      {
        'devDependencies': [
          '**/*.stories.jsx',
          '**/*.stories.tsx',
          '**/*.test.jsx',
          '**/*.test.js',
          '**/*.test.tsx',
          '**/*.test.ts',
          'setupTests.js',
        ],
      },
    ],
    '@typescript-eslint/camelcase': ['error', { 'properties': 'never' }],
    'indent': 'off',
    '@typescript-eslint/indent': [
      'error',
      2,
      {
        'ignoredNodes': ['JSXElement'],
        'SwitchCase': 1,
      },
    ],
    '@typescript-eslint/explicit-function-return-type': ['error', {
      'allowExpressions': true,
      'allowTypedFunctionExpressions': true
    }],
    'semi': 'off',
    '@typescript-eslint/semi': ['error'],
    'react/destructuring-assignment': [false, 'always', { 'ignoreClassFields': true }],
    'react/jsx-filename-extension': [1, { 'extensions': ['.jsx', '.tsx'] }],
  },
  settings: {
    'import/extensions': [
      '.js',
      '.jsx',
      '.ts',
      '.tsx',
    ],
    'import/resolver': {
      webpack: {
        config: 'webpack.common.js',
      }
    }
  },
};

You have to declare members before you can use them.

Try this:


export default class Navigation extends React.Component<{}, MyState> {
  // Declare the private member variable
  private childNavRef: React.RefObject<HTMLDivElement>; 

  public constructor() {
    super({});
    this.state = {
      show: true,
    };
    this.childNavRef = React.createRef();
  }
  ...

You can also try this and let TypeScript automatically infer the variable type:


export default class Navigation extends React.Component<{}, MyState> {
  // Declare AND initialize the private member variable
  private childNavRef = React.createRef();

  public constructor() {
    super({});
    this.state = {
      show: true,
    };

    // Note that you no longer have to instantiate childNavRef here anymore, 
    // as TypeScript will do that automatically (it will actually compile to something
    // like in the first example, where ref is set after the super call in the constructor).
  }
  ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM