简体   繁体   English

React typescript - 类型“boolean”不可分配给类型

[英]React typescript - Type 'boolean' is not assignable to type

I have a demo我有一个演示

It's a simple React app using Typescript.这是一个使用 Typescript 的简单 React 应用程序。

I'm trying to use Reacts Context api我正在尝试使用 Reacts 上下文 api

I've created a context ThemeContext with simple theme styling values to use in other components.我创建了一个具有简单主题样式值的上下文ThemeContext以用于其他组件。

I'm then using this theme context to styled a list of books Booklist.tsx然后我使用这个主题上下文来设置书籍Booklist.tsx的样式

I want a button to update the theme我想要一个按钮来更新主题

I have a themetoggle in the context that I'm trying to call from the ThemeToggle component.我在尝试从 ThemeToggle 组件调用的上下文中有一个 themetoggle。

My problem is the onClick in this ThemeToggle I get the error我的问题是这个 ThemeToggle 中的 onClick 我收到错误

(JSX attribute) React.DOMAttributes<HTMLButtonElement>.onClick?: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void

Type 'boolean' is not assignable to type '(event: MouseEvent<HTMLButtonElement, MouseEvent>) => void'.(2322)

ThemeToggle.tsx(23, 29): The expected type comes from property 'onClick' which is declared here on type 'DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>'

I'm sure this is a typescript error but not sure how to fix it.我确定这是一个 typescript 错误,但不确定如何修复它。

Whats casuing this error on the onClick, how can I fix it onClick出现这个错误是怎么回事,我该如何解决

index.tsx索引.tsx

import React from 'react';
import BookList from './Booklist';
import ThemeContextProvider from './ThemeContext';
import { render } from "react-dom";
import ThemeToggle from './ThemeToggle';
import './style.css'

const App:React.FC = () => {
  return (
    <div className="App">
      <ThemeContextProvider>
        <BookList />
        <ThemeToggle/>
      </ThemeContextProvider>
    </div>
  );
}

export default App;
render(<App />, document.getElementById("root"));

ThemeContext.tsx ThemeContext.tsx

import React, {createContext} from 'react'

export interface Props {}

export interface State {
    lightTheme: boolean
    light:{syntax: string, ui: string, bg: string}
    dark:{syntax: string, ui: string, bg: string}
    toggleTheme:boolean
}

const defaultState:State = {
    lightTheme: true,
    light:{syntax:'', ui:'', bg:''},
    dark:{syntax:'', ui:'', bg:''},
    toggleTheme:false
}

export const ThemeContext = createContext(defaultState)

class ThemeContextProvider extends React.Component<Props, State> {

    constructor(props: Props){
        super(props)

        this.state = { 
            lightTheme: true,
            light: {syntax: '#333', ui: 'pink', bg: '#bbb'},
            dark: {syntax: '#ddd', ui: '#333', bg: '#555'},
            toggleTheme: false
        }
    }

    toggleTheme = () => {
        this.setState({ lightTheme: !this.state.lightTheme})
    }

    render() { 
        return (  
            <ThemeContext.Provider value={{...this.state, toggleTheme: this.state.toggleTheme}}>
                {this.props.children}
            </ThemeContext.Provider>
        );
    }
}

export default ThemeContextProvider;

Booklist.tsx书单.tsx

import React from 'react'
import { ThemeContext } from './ThemeContext';

export interface Props {}

export interface State {
    lightTheme: boolean
    light:Darkness
    dark:Darkness
}

interface Darkness{
    syntax: string
    ui: string
    bg: string 
}

class BookList extends React.Component<Props, State> {
    render() { 
      return(
        <ThemeContext.Consumer>
        {(state) => {
          const { lightTheme, light, dark} = state
          const theme = lightTheme ? light : dark
          return(
                  <div style={{color: theme.syntax, background: theme.bg}}>
                      <ul>
                          <li style={{background:theme.ui}}>Book One</li>
                          <li style={{background:theme.ui}}>Book Two</li>
                      </ul>
                  </div>
          )
        }}</ThemeContext.Consumer>
      )
    }
}

export default BookList;        

ThemeToggle主题切换

import * as React from 'react';
import { ThemeContext } from './ThemeContext';

export interface ThemeToggleProps {}

export interface ThemeToggleState {}

class ThemeToggle  extends React.Component<ThemeToggleProps, ThemeToggleState> {
    render() { 
        return ( 
            <ThemeContext.Consumer>
                {(state) => {
                    const {toggleTheme} = state
                    return(
                        <button onClick={toggleTheme}>Toggle Theme</button>
                    )
                }}
            </ThemeContext.Consumer>
         );
    }
}

export default ThemeToggle ;    

Like @PhilipFeldmann wrote in their comment, the onclick attribute expects a function, not a boolean.正如@PhilipFeldmann 在他们的评论中所写, onclick属性需要一个 function,而不是 boolean。

You declare the interface State in ThemeContext.tsx:12, where the property toggleTheme is declared as boolean. You keep that up, assigning the property in the const defaultState a boolean value, same when you assign ThemeContextProvider.state with an object whose toggleTheme property is a boolean. Then you pass that down to the ThemeToggle class, where toggleTheme is still a boolean (ThemeToggle.tsx:13).您在 ThemeContext.tsx:12 中声明接口State ,其中属性toggleTheme声明为 boolean。您保持这一点,为 const defaultState中的属性分配一个 boolean 值,当您分配ThemeContextProvider.state时相同,其 toggle 属性为toggleTheme是 boolean。然后将其传递给 ThemeToggle class,其中 toggleTheme 仍然是 boolean (ThemeToggle.tsx:13)。

You can fix that by changing the declaration of the State interface so that toggleTheme takes a function instead:您可以通过更改State接口的声明来解决此问题,以便toggleTheme取而代之的是 function:

// ThemeContext.tsx:5
export interface State {
    lightTheme: boolean
    light:{syntax: string, ui: string, bg: string}
    dark:{syntax: string, ui: string, bg: string}
    toggleTheme:() => void
}
// ThemeContext.tsx:12
const defaultState:State = {
    lightTheme: true,
    light:{syntax:'', ui:'', bg:''},
    dark:{syntax:'', ui:'', bg:''},
    toggleTheme: () => {}
}
// ThemeContext.tsx:26
this.state = { 
    lightTheme: true,
    light: {syntax: '#333', ui: 'pink', bg: '#bbb'},
    dark: {syntax: '#ddd', ui: '#333', bg: '#555'},
    toggleTheme: this.toggleTheme
}

With that the button will work.这样按钮就可以工作了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无效类型不能分配给布尔类型(反应/打字稿) - Type Void is Not Assignable to Type Boolean (React/Typescript) TypeScript 错误:类型 &#39;() =&gt; boolean&#39; 不可分配给类型 &#39;boolean&#39; - TypeScript error: Type '() => boolean' is not assignable to type 'boolean' 使用TypeScript进行反应:类型“ {}”不可分配给类型 - React with TypeScript: Type '{}' is not assignable to type 如何使用react和typescript修复错误“类型参数(打开:任何)=&gt;布尔值不能分配给布尔类型的参数”? - How to fix error "argument of type (open: any) => boolean is not assignable to parameter of type boolean" using react and typescript? 类型不可分配(React + Typescript + Firebase) - Type not assignable (React + Typescript + Firebase) React Typescript不可分配给type参数 - React typescript is not assignable to parameter of type 与TypeScript反应 - 类型{...}不能分配给'Readonly <S>' - React with TypeScript - Type {…} is not assignable to type 'Readonly<S>' React TypeScript:类型“string []”不可分配给类型“never []” - React TypeScript: Type 'string[]' is not assignable to type 'never[]' 如何使用 react 和 typescript 修复错误“false 类型的参数不可分配给 (currentValue: boolean) =&gt; boolean”? - How to fix error “argument of type false is not assignable to (currentValue: boolean) => boolean” using react and typescript? React Typescript,类型''不可分配给类型'null' - React Typescript, Type '' is not assignable to type 'null'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM