Quantcast
Channel: Active questions tagged react-native+typescript - Stack Overflow
Viewing all 6202 articles
Browse latest View live

Visual Studio Code:[js] types can only be used in a .ts file

$
0
0

Is it possible to use .js files in a typescript project in vs code? I have clone a react-native project from a github repository and opened it in visual studio code. When I add a tsconfig.json in order to start using typescript, I get a long list of errors. For example here is a drawer.js file (with es6 features):

enter image description here

Here is my tsconfig.json file (If I remove this file then every thing works fine, no error reported) :

enter image description here


Why is State returning empty first in React TypeScript & Property does not exist on type 'never'?

$
0
0

I'm trying to work with state in react using typescript. In the line "return monster.name.toLowerCase().includes(search)" I'm getting this error message "Property 'name' does not exist on type 'never'." The API can be found here https://jsonplaceholder.typicode.com/users. What i'm i doing wrong her or what am I missing or not doing.

import React, { Component } from 'react';
import './App.css';
import CardList from './Components/CardList/CardList';

interface IProps {
  superhero: string;
}

interface IState {
  monsters: [],
  search: string,
}

class App extends Component<IProps, IState> {

  state: IState;

  constructor(props: IProps){

    super(props);

    this.state = {
      monsters: [],
      search: '',
    }

  }

  componentDidMount(){
    fetch('https://jsonplaceholder.typicode.com/users')
    .then(response => response.json())
    .then(users => this.setState({monsters: users}))
  }

  render(){

    interface IContact {
      id: number;
      name: string;
  }

    const searchMonsters = (e: any) => {
      console.log(e.target.value)
      this.setState(
        { 
          search: e.target.value
        }
      );

    }

    const { monsters, search } = this.state;

    //return monster.name.toLowerCase().includes(search) giving error Property 'name' does not exist on type 'never'

    const filteredMonsters = monsters.filter( monster => {
      return monster.name.toLowerCase().includes(search)
    });


    console.log(this.state.monsters);


    return (
      <div className="App">
        <input type="search" placeholder="Search Monster" onChange={searchMonsters}/>
        <CardList monsters={filteredMonsters}/>
      </div>
    );

  }

}

export default App;

React-Native wrapping a typed class into functional component for styling

$
0
0

I am wrapping components into functional components in order to perform consistent styling. This works pretty good most of the time, but if the wrapped component has generics in their properties things get a little messy. Specifically I cant wrap my head around the FlatList component and how to define the ItemT.

  type Props<ItemT> = React.ComponentProps<typeof FlatList> & {
     theme: Theme
  }

  const MyFlatList = <ItemT extends {}>(props: Props<ItemT>) => {
     const { theme } = props

     return <FlatList {...props} contentContainerStyle={{ backgroundColor: theme.colors.background }} />
  }

  export default withTheme(MyFlatList)

This basically matches what react-native-paper recommends here https://callstack.github.io/react-native-paper/theming.html#customizing-all-instances-of-a-component. While this compiles without errors the type information is lost, if I am using this component in my code.

<MyFlatList
      data={items}
      keyExtractor={item => item.id}
      renderItem={({ item }) => renderItem(item)}
    />

The item in this case is of type unknown whereas in plain FlatList the type is properly derived. I guess the problem is ItemT extends {}, but I haven't found any other way to let the caller define the ItemT. Any thought?

React Native content is not going to the next row

$
0
0

I am currently facing a styling issue.

What am I trying to achieve

I want to display a list of movies.

There should be around two or three movies showed per row (depending on the available space on the device).

If the list gets too long, then the user should be able to scroll vertically.

Current situation

The list of movies does not break into the next row.

See for yourself, the picture describes the issue the best

Code that I am using to achieve my goal

<ScrollView style={styles.moviesContainer} contentContainerStyle={{flexDirection: "row"}}>
                    <Movie></Movie>
                    <Movie></Movie>
                    <Movie></Movie>
                    <Movie></Movie>
                    <Movie></Movie>
                    <Movie></Movie>
                </ScrollView>

^ The moviesContainer styling only contains some margins/border.

I hope that someone can help me with this issue, but if there is something unclear, please let me know so I can add it to this question!

Typescript optional chaining error: Expression expected.ts(1109)

$
0
0

I am trying to do optional chaining in Typescript + React Native.

Let's say I have the following interfaces:

interface Bar {
  y: number
}

interface Foo {
  x?: Bar
}

and I try to run the following:

 const test: Foo = {x: {y: 3}};
 console.log(test.x?.y);

VSCode will show an error under the ?. saying the following: Expression expected.ts(1109)

Do you have any idea why this is happening or how should I fix it? Thanks.

React Context Api

$
0
0

Im developing a products table with checkboxes on the side, the check box job is to send the Id of the choosen product once its clicked to it's grandfather so i can build an array of the choosen ones and send them via api.

Its built like this:

grandfather - Table page component.

father - The table itself.

child - The checkbox component.

basically I'm having trouble how to pass the information, i know i should use context api but the syntax is confusing me, here's the code:

Grandfather:

interface Istate {
  Select: boolean;
  SelectT: boolean;
  SelectI: boolean;
  Loader: boolean;
  numOfProds: number;
  listing: any;
  checkBoxId: any;
  prodName: string;
  quantity: number;
  price: number;
  TempProdName: string;
  TempQuantity: number;
  TempPrice: number;
}

interface Iprops {
  id: string;
  name: string;
}

class Products extends Component<Iprops, Istate> {
  state = {
    Select: false,
    SelectT: false,
    SelectI: false,
    Loader: false,
    numOfProds: 0,
    listing: Array,
    checkBoxId: '',
    prodName: '',
    quantity: 0,
    price: 0,
    TempProdName: '',
    TempQuantity: 0,
    TempPrice: 0,
  };

  async componentDidMount() {
    this.showLoader();
    const listing = await AllProductsService.AllProducts();
    this.setState({ listing });
    console.log(listing);
    this.setState({ numOfProds: listing.length });
    this.hideLoader();
  }

  toggleSelect = () => {
    const { Select } = this.state;
    this.setState({ Select: !Select });
  };

  toggleSelect2 = () => {
    const { SelectT } = this.state;
    this.setState({ SelectT: !SelectT });
  };

  toggleSelect3 = () => {
    const { SelectI } = this.state;
    this.setState({ SelectI: !SelectI });
  };

  showLoader = () => {
    this.setState({ Loader: true });
  };

  hideLoader = () => {
    this.setState({ Loader: false });
  };

  CancelValue = () => {
    const { prodName, quantity, price, TempPrice, TempProdName, TempQuantity } = this.state;
    this.setState({ TempProdName: prodName });
    this.setState({ TempQuantity: quantity });
    this.setState({ TempPrice: price });
  };

  changeValue = (checkBoxId: any, value: any) => {
    this.setState({
      [checkBoxId]: value,
    } as any);
  };

  render() {
    const {
      Select,
      SelectT,
      SelectI,
      listing,
      numOfProds,
      Loader,
      checkBoxId,
      prodName,
      quantity,
      price,
      TempProdName,
      TempQuantity,
      TempPrice,
    } = this.state;
    const { name, id } = this.props;
    return (
      <ProductTableProvider
        value={{
          prodName,
          quantity,
          price,
          checkBoxId,
          changeValue: this.changeValue,
        }}
      >
        <Breadcrumb path1="/overview" one="Dashboard" path2="/dashboard/products" two="All Products" />
        <InsideWrapper>
          <Platform>
            <h2>Products</h2>
            <br />
            <p>Manage your products</p>
            <CardStat header="Total" numOf={numOfProds} page="Products" />
            <CardStat header="Ebay" numOf={numOfProds} page="Products" />
            <div className="col-sm text-center new w-100">
              <div className="text-right mb-4">
                <GreenButton onClick={this.toggleSelect3}>Export to Ebay</GreenButton>
                <SimpleModal isOpen={SelectI} close={this.toggleSelect3} whatToDo={`Export ${name} to Ebay?`}>
                  <YesNoButton name={name} id={id} />
                </SimpleModal>
                <RegularButton onClick={this.toggleSelect}>Save</RegularButton>
                <SimpleModal isOpen={Select} close={this.toggleSelect} whatToDo="Are you sure you want to save?">
                  <YesNoButton name={name} id={id} />
                </SimpleModal>
                <OrangeButton onClick={this.CancelValue}>Cancel</OrangeButton>
                <DeleteButton onClick={this.toggleSelect2}>Delete</DeleteButton>
                <SimpleModal isOpen={SelectT} close={this.toggleSelect2} whatToDo="Are you sure you want to delete?">
                  <YesNoButton name={name} id={id} />
                </SimpleModal>
              </div>
              <Card>{Loader ? <Loading /> : <DatatablePage listing={listing} />}</Card>
            </div>
          </Platform>
        </InsideWrapper>
      </ProductTableProvider>
    );
  }
}
export default Products;

Father:

const DatatablePage = (props: any) => {
  const { listing } = props;
  const rows = Array.isArray(listing)
    ? listing.map((val: any) => {
        return {
          select: <CheckBoxComp value={false} id={val._id} />,
          name: <TableText value={val.name} id={val._id} />,
          barcode: val._id,
          category: val.category,
          image: <ImageSec src={ImageProd} />,
          unitsInStock: <TableText value={val.unitsInStock} id={val._id} />,
          price: <TableText value={val.price} id={val._id} />,
          more: <ButtonsPopUp name={val.name} id={val._id} />,
        };
      })
    : [];
  const data = {
    columns: [
      {
        label: '',
        field: '',
        sort: 'disabled',
        width: 20,
      },
      {
        label: 'Name',
        field: 'name',
        sort: 'asc',
        width: 100,
      },
      {
        label: 'Barcode',
        field: 'barcode',
        sort: 'asc',
        width: 100,
      },
      {
        label: 'Category',
        field: 'category',
        sort: 'asc',
        width: 100,
      },
      {
        label: 'Images',
        field: 'images',
        sort: 'asc',
        width: 100,
      },
      {
        label: 'Quantity',
        field: 'unitsInStock',
        sort: 'asc',
        width: 150,
      },
      {
        label: 'Price',
        field: 'price',
        sort: 'asc',
        width: 150,
      },
      {
        label: '...',
        field: 'more',
        sort: 'disabled',
        width: 100,
      },
    ],
    rows,
  };
  return (
    <Rules>
      <MDBDataTable
        entriesLabel="Show Products"
        infoLabel={['Showing', 'to', 'of', 'Products']}
        fixed
        responsive
        btn
        sortable
        hover
        data={data}
        theadColor="white"
      />
    </Rules>
  );
};

export default DatatablePage;

Child:

interface Istate {
  checked: boolean;
  products?: any[];
}
interface Iprops {
  id: any;
  value: any;
  changeValue?: (checkBoxId: string, value: any) => void;
}
class CheckBoxComp extends Component<Iprops, Istate> {
  state = {
    checked: true,
    products: [] as any,
  };

  addOne = (id: any, checked: any) => {
    let { products } = this.state;
    const newObj = { id, checked };
    products = products.concat(newObj);
    this.setState({ products }, () => {
      console.log(products);
    });
  };

  isChecked = (id: any) => {
    const { checked, products } = this.state;
    const { changeValue } = this.props;
    console.log(id);
    this.setState({
      checked: !checked,
    });
    if (changeValue) {
      changeValue(id, checked);
    }
    this.addOne(id, checked);
  };

  render() {
    const { id, value } = this.props;
    const { checked } = this.state;
    return (
      <Fragment>
        <Checkbox>
          <span />{''}
          <label className="checkbox-wrapper">
            <span className="display" />
            <Inputt type="checkbox" value={checked} onChange={this.isChecked.bind(this, id)} />
            <span className="checkmark" />
          </label>
        </Checkbox>
      </Fragment>
    );
  }
}

export default CheckBoxComp;

any help wrapping the code correctly using context api?

Why does eslint fail on Github Actions but works locally?

$
0
0

I have a workflow that looks like this

name: Node CI

on: [push]

jobs:
  build:

    runs-on: ubuntu-18.04

    steps:
    - uses: actions/checkout@v1
    - uses: actions/setup-node@v1
      with:
        node-version: '12.x'
    - run: npm install
    - run: npm run lint

For some reason the lint stage fails and produces the following error

> eslint . --ext .js,.jsx,.ts,.tsx


/home/runner/work/ABC/ABC/src/components/folder/Folder.tsx
##[error]  6:20  error  Missing file extension for "../../styles/Colors"        import/extensions
##[error]  6:20  error  Unable to resolve path to module '../../styles/Colors'  import/no-unresolved

/home/runner/work/ABC/ABC/src/components/todo/header/Heading.tsx
##[error]  4:20  error  Missing file extension for "../../../styles/Colors"        import/extensions
##[error]  4:20  error  Unable to resolve path to module '../../../styles/Colors'  import/no-unresolved


/home/runner/work/ABC/ABC/src/screens/TodoScreen.tsx
##[error]  3:20  error  Missing file extension for "../styles/Colors"        import/extensions
##[error]  3:20  error  Unable to resolve path to module '../styles/Colors'  import/no-unresolved

✖ 6 problems (6 errors, 0 warnings)

When I run npm run lint locally, it successfully passes.

I've tried running npm ci and then npm run lint and it still passes

Why hasOwnProperty method doesn't eliminate {} type

$
0
0

I have a complex type ReactNode from @types/react 16.9.17 version and TypeScript v3.7.4 version.

import React, { ReactNode } from 'react';

and I want to reduce this type to type, which has property children.

I'm trying to achieve this using implicit type-guards:

import React, { ReactNode } from 'react';

function func(x: ReactNode) {
  if (typeof x === 'object'&& x !== null && x.hasOwnProperty("children")) {
    x.children
  }
}

but I see error Property 'children' does not exist on type '{}'.

Questions:

  1. Why I see this error (why typescript doesn't eliminate empty {} type after hasOwnProperty() check)?

  2. How in general eliminate {} type from {} | Type types?

  3. How to reduce ReactNode type to type, having children property?

enter image description here


How to test type definition file for react or react-native project?

$
0
0

I am a maintainer of a react and react-native library/sdk. We also provide type (typescript) definitions for the components that we export. But its a bit hard to manually keep actual components and type definitions in sync, especially when 10 different devs are working on it in parallel. Also its quite hard to test if the provided definitions are accurate without actually using every prop in sample TS project. Has anyone also faced the same issue and/or figured out some easier way to tackle this problem?

What I am looking for is a way to test the type definition file for react type of project.

Type 'Element | undefined' is not assignable to type 'FC | undefined'

$
0
0

In this MainHeader component:

<MainHeader
  LeftButton={
    previous ? (
      <BackButton
        onPress={() => {
          navigation.goBack;
        }}
      />
    ) : (
      undefined
    )
  }
  ...
/>

BackButton is a JSX element passed down through the LeftButton prop to MainHeader and is explicitly typed as const BackButton: React.FC<BackButtonProps>, so then I would expect the LeftButton prop to be typed as follows:

interface MainHeaderProps {
  LeftButton: React.FC<any> | undefined;
  ...
}

But I get this error when trying to assign BackButton | undefined to the LeftButton prop: Type 'Element | undefined' is not assignable to type 'FC<any> | undefined'. ...so I change my type to

interface MainHeaderProps {
  LeftButton: JSX.Element | undefined;
  ...
}

Error goes away. But now I get an error when I try to use <LeftButton /> in MainHeader: JSX element type 'LeftButton' does not have any construct or call signatures. So after doing some reading I'm even more confused about what type I should be using... I try many different types from @types/react like ComponentType to try and define LeftButton by its constructor, but TypeScript enforces that LeftButton be typed as JSX.Element, so I'm not sure how to best resolve this.

React Native referenced object seems to be undefined

$
0
0

I am trying to assign data retrieved from an API into an array, however whenever the data is called my project crashed and I get an error saying TypeError: undefined is not an object (evaluating 'this.data.name')

Here is all my code regarding the variable data

    constructor(props){
    super(props);
    this.state={
      data : [],
      }
    }
async  componentDidMount(){
    try {
    const id = this.props.navigation.state.params.info

    const res = await axios.request({
      method: 'get',
      url: `https://developers.zomato.com/api/v2.1/restaurant?res_id=${id}`,
      headers: {
        'Content-Type': 'application/json',
        'user-key': 'a31bd76da32396a27b6906bf0ca707a2'
      }
    });
    this.setState({ data: res.data });
  } catch (err) {
    console.log(err);
  } finally {
    this.setState({ isLoading: false });
  }
  };

  render() {
    return (
    <View>        
        {this.state.isLoading ?
            <View style={{ flex: 1, marginTop: 200 }}>
              <ActivityIndicator style={{color:'red'}} />
            </View> :

        <View><Text>{this.data.name}</Text></View>
        }
    </View>
)}

React Native Typescript Formik typings of handleSubmit in onPress

$
0
0

I just started a project on React Native with Typescript and came along Formik in order to build form in my application.

I did the great formik tutorial guide and saw the use of formik with RN section in JS.

However, when I tried to translate this example into typescript, then I got the following typing error on the Button's onPress attribute:

No overload matches this call.
  Overload 1 of 2, '(props: Readonly<ButtonProps>): Button', gave the following error.
    Type '(e?: FormEvent<HTMLFormElement>) => void' is not assignable to type '(ev: NativeSyntheticEvent<NativeTouchEvent>) => void'.
      Types of parameters 'e' and 'ev' are incompatible.
        Type 'NativeSyntheticEvent<NativeTouchEvent>' is not assignable to type 'FormEvent<HTMLFormElement>'.
          Types of property 'nativeEvent' are incompatible.
            Type 'NativeTouchEvent' is missing the following properties from type 'Event': bubbles, cancelBubble, cancelable, composed, and 17 more.
  Overload 2 of 2, '(props: ButtonProps, context?: any): Button', gave the following error.
    Type '(e?: FormEvent<HTMLFormElement>) => void' is not assignable to type '(ev: NativeSyntheticEvent<NativeTouchEvent>) => void'.ts(2769)
index.d.ts(6926, 5): The expected type comes from property 'onPress' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<Button> & Readonly<ButtonProps> & Readonly<{ children?: ReactNode; }>'
index.d.ts(6926, 5): The expected type comes from property 'onPress' which is declared here on type 'IntrinsicAt...

From what I understand, the handleSubmit function (e?: FormEvent<HTMLFormElement>) => void, accepts an event from a form submission (onSubmit attribute of a form element). Since there is no Form equivalent in RN, it complains receiving the (ev: NativeSyntheticEvent<NativeTouchEvent>) => void from the RN Button's onPress attribute.

In order to get rid of the error and keep going, I used this following workaround which I'm not satisfied with :

<Button
              title="Do it !"
              color={colors.red}
              onPress={
                (handleSubmit as unknown) as (
                  ev: NativeSyntheticEvent<NativeTouchEvent>
                ) => void
              }
/>

I'd like to know how should I solve this typing error properly.

CodeSandbox: App.tsx:32

Thank you for your help.

React Native -> React Native Web with webpack and JSX

$
0
0

I started a new React Native project (v61.5) with the TypeScript template (npx react-native init MyTSProject --template react-native-template-typescript). It compiles fine with React Native but when I try to add webpack (for React Native Web) I get JSX/TSX errors (I think). Am I doing something wrong with webpack here?

tsconfig.json

{
  "compilerOptions": {
    /* Basic Options */
    "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
    "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
    "lib": [ "es5", "es6", "dom" ],           /* Specify library files to be included in the compilation. */
    "allowJs": true,                          /* Allow javascript files to be compiled. */
    // "checkJs": true,                       /* Report errors in .js files. */
    "jsx": "react-native",                    /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
    // "declaration": true,                   /* Generates corresponding '.d.ts' file. */
    // "sourceMap": true,                     /* Generates corresponding '.map' file. */
    // "outFile": "./",                       /* Concatenate and emit output to single file. */
    // "outDir": "./",                        /* Redirect output structure to the directory. */
    // "rootDir": "./",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    "removeComments": true,                   /* Do not emit comments to output. */
    // "noEmit": true,                        /* Do not emit outputs. */
    "incremental": true,                      /* Enable incremental compilation */
    "importHelpers": true,                    /* Import emit helpers from 'tslib'. */
    "downlevelIteration": true,               /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
    "isolatedModules": true,                  /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */

    /* Strict Type-Checking Options */
    "strict": true,                           /* Enable all strict type-checking options. */
    // "noImplicitAny": true,                 /* Raise error on expressions and declarations with an implied 'any' type. */
    // "strictNullChecks": true,              /* Enable strict null checks. */
    // "strictFunctionTypes": true,           /* Enable strict checking of function types. */
    // "strictPropertyInitialization": true,  /* Enable strict checking of property initialization in classes. */
    // "noImplicitThis": true,                /* Raise error on 'this' expressions with an implied 'any' type. */
    // "alwaysStrict": true,                  /* Parse in strict mode and emit "use strict" for each source file. */

    /* Additional Checks */
    // "noUnusedLocals": true,                /* Report errors on unused locals. */
    // "noUnusedParameters": true,            /* Report errors on unused parameters. */
    // "noImplicitReturns": true,             /* Report error when not all code paths in function return a value. */
    // "noFallthroughCasesInSwitch": true,    /* Report errors for fallthrough cases in switch statement. */

    /* Module Resolution Options */
    "moduleResolution": "node",               /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
    "baseUrl": "./",                          /* Base directory to resolve non-absolute module names. */
    // "paths": {},                           /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
    // "rootDirs": [],                        /* List of root folders whose combined content represents the structure of the project at runtime. */
    // "typeRoots": [],                       /* List of folders to include type definitions from. */
    // "types": [],                           /* Type declaration files to be included in compilation. */
    "allowSyntheticDefaultImports": true,     /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
    "esModuleInterop": true,                  /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    // "preserveSymlinks": true,              /* Do not resolve the real path of symlinks. */

    /* Source Map Options */
    // "sourceRoot": "./",                    /* Specify the location where debugger should locate TypeScript files instead of source locations. */
    // "mapRoot": "./",                       /* Specify the location where debugger should locate map files instead of generated locations. */
    // "inlineSourceMap": true,               /* Emit a single file with source maps instead of having a separate file. */
    // "inlineSources": true,                 /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */

    /* Experimental Options */
    // "experimentalDecorators": true,        /* Enables experimental support for ES7 decorators. */
    // "emitDecoratorMetadata": true,         /* Enables experimental support for emitting type metadata for decorators. */

    "resolveJsonModule": true,
  },
  "exclude": [
    "node_modules", "babel.config.js", "metro.config.js", "jest.config.js"
  ]
}

webpack.config.js

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const rootDir = path.join(__dirname, '..');
const webpackEnv = process.env.NODE_ENV || 'development';

module.exports = {
  mode: webpackEnv,
  entry: {
    app: path.join(rootDir, './index.web.ts'),
  },
  output: {
    path: path.resolve(rootDir, 'dist'),
    filename: 'app-[hash].bundle.js',
  },
  devtool: 'source-map',
  module: {
    rules: [
      {
        test: /\.(tsx|ts|jsx|js|mjs)$/,
        exclude: /node_modules/,
        use: [ 'ts-loader' ],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.join(__dirname, './index.html'),
    }),
    new webpack.HotModuleReplacementPlugin(),
  ],
  resolve: {
    extensions: [
      '.web.tsx',
      '.web.ts',
      '.tsx',
      '.ts',
      '.web.jsx',
      '.web.js',
      '.jsx',
      '.js',
    ], // read files in following order
    alias: Object.assign({
      'react-native$': 'react-native-web',
    }),
  },
};

TypeScript (As from the React Native demo app) import React from 'react'; import { SafeAreaView, StyleSheet, ScrollView, View, Text, StatusBar, } from 'react-native';

import {
  Header,
  LearnMoreLinks,
  Colors,
  DebugInstructions,
  ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';

declare var global: {HermesInternal: null | {}};

const App = () => {
  return (
    <>
      <StatusBar barStyle="dark-content" />
      <SafeAreaView>
        <ScrollView
          contentInsetAdjustmentBehavior="automatic"
          style={styles.scrollView}>
          <Header />
          {global.HermesInternal == null ? null : (
            <View style={styles.engine}>
              <Text style={styles.footer}>Engine: Hermes</Text>
            </View>
          )}
          <View style={styles.body}>
            <View style={styles.sectionContainer}>
              <Text style={styles.sectionTitle}>Step One</Text>
              <Text style={styles.sectionDescription}>
                Edit <Text style={styles.highlight}>App.tsx</Text> to change this
                screen and then come back to see your edits.
              </Text>
            </View>
            <View style={styles.sectionContainer}>
              <Text style={styles.sectionTitle}>See Your Changes</Text>
              <Text style={styles.sectionDescription}>
                <ReloadInstructions />
              </Text>
            </View>
            <View style={styles.sectionContainer}>
              <Text style={styles.sectionTitle}>Debug</Text>
              <Text style={styles.sectionDescription}>
                <DebugInstructions />
              </Text>
            </View>
            <View style={styles.sectionContainer}>
              <Text style={styles.sectionTitle}>Learn More</Text>
              <Text style={styles.sectionDescription}>
                Read the docs to discover what to do next:
              </Text>
            </View>
            <LearnMoreLinks />
          </View>
        </ScrollView>
      </SafeAreaView>
    </>
  );
};

const styles = StyleSheet.create({
  scrollView: {
    backgroundColor: Colors.lighter,
  },
  engine: {
    position: 'absolute',
    right: 0,
  },
  body: {
    backgroundColor: Colors.white,
  },
  sectionContainer: {
    marginTop: 32,
    paddingHorizontal: 24,
  },
  sectionTitle: {
    fontSize: 24,
    fontWeight: '600',
    color: Colors.black,
  },
  sectionDescription: {
    marginTop: 8,
    fontSize: 18,
    fontWeight: '400',
    color: Colors.dark,
  },
  highlight: {
    fontWeight: '700',
  },
  footer: {
    color: Colors.dark,
    fontSize: 12,
    fontWeight: '600',
    padding: 4,
    paddingRight: 12,
    textAlign: 'right',
  },
});

export default App;

Output/Error

ℹ 「wds」: Project is running at http://localhost:8080/
ℹ 「wds」: webpack output is served from /
ℹ 「wds」: Content not from webpack is served from /home/nick/MyTSProject/web
✖ 「wdm」: Hash: e739fe310ea105fb05fe
Version: webpack 4.41.5
Time: 4672ms
Built at: 12/30/2019 8:13:55 PM
                                 Asset       Size  Chunks                         Chunk Names
    app-e739fe310ea105fb05fe.bundle.js   2.48 MiB     app  [emitted] [immutable]  app
app-e739fe310ea105fb05fe.bundle.js.map   2.63 MiB     app  [emitted] [dev]        app
                            index.html  438 bytes          [emitted]              
Entrypoint app = app-e739fe310ea105fb05fe.bundle.js app-e739fe310ea105fb05fe.bundle.js.map
[0] multi ../node_modules/webpack-dev-server/client?http://localhost:8080 ../index.web.ts 40 bytes {app} [built]
[../app.json] 60 bytes {app} [built]
[../index.web.ts] 496 bytes {app} [built]
[../node_modules/react-native-web/dist/index.js] 4.3 KiB {app} [built]
[../node_modules/tslib/tslib.es6.js] 9.21 KiB {app} [built]
[../node_modules/webpack-dev-server/client/index.js?http://localhost:8080] ../node_modules/webpack-dev-server/client?http://localhost:8080 4.29 KiB {app} [built]
[../node_modules/webpack-dev-server/client/overlay.js] 3.51 KiB {app} [built]
[../node_modules/webpack-dev-server/client/socket.js] 1.53 KiB {app} [built]
[../node_modules/webpack-dev-server/client/utils/createSocketUrl.js] 2.91 KiB {app} [built]
[../node_modules/webpack-dev-server/client/utils/log.js] 964 bytes {app} [built]
[../node_modules/webpack-dev-server/client/utils/reloadApp.js] 1.59 KiB {app} [built]
[../node_modules/webpack-dev-server/client/utils/sendMessage.js] 402 bytes {app} [built]
[../node_modules/webpack-dev-server/node_modules/strip-ansi/index.js] 161 bytes {app} [built]
[../node_modules/webpack/hot sync ^\.\/log$] ../node_modules/webpack/hot sync nonrecursive ^\.\/log$ 170 bytes {app} [built]
[../source/App.tsx] 438 bytes {app} [built] [failed] [1 error]
    + 255 hidden modules

ERROR in ../source/App.tsx 8:12
Module parse failed: Unexpected token (8:12)
File was processed with these loaders:
 * ../node_modules/ts-loader/index.js
You may need an additional loader to handle the result of these loaders.
| var NewAppScreen_1 = require("react-native/Libraries/NewAppScreen");
| var App = function () {
>     return (<>
|       <react_native_1.StatusBar barStyle="dark-content"/>
|       <react_native_1.SafeAreaView>
 @ ../index.web.ts 6:36-59
Child html-webpack-plugin for "index.html":
     1 asset
    Entrypoint undefined = index.html
    [../node_modules/html-webpack-plugin/lib/loader.js!./index.html] 566 bytes {0} [built]
    [../node_modules/lodash/lodash.js] 528 KiB {0} [built]
    [../node_modules/webpack/buildin/global.js] 472 bytes {0} [built]
    [../node_modules/webpack/buildin/module.js] 497 bytes {0} [built]
ℹ 「wdm」: Failed to compile.

I have tried alternative loaders (babel-loader, awesome-typescript-loader). I have tried various chat rooms. I have read many, many blog posts (although they almost all seem to be from years ago and no longer apply).

No idea where to go from here.

How to use prop-types as type definition in typescript?

$
0
0

Situation:

Consider having the myTypes constant holding prop-types (written somewhere in a file called my-component.js), like below:

import React from 'react'
import { View } from 'react-native'
import PropTypes from 'prop-types'

export const myTypes = {
  activeColor: PropTypes.string,
  color: PropTypes.string,
  fontFamily: PropTypes.string,
  fontSize: PropTypes.number,
  fontWeight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  height: PropTypes.number,
  icon: PropTypes.node,
  iconOverlay: PropTypes.node,
  marginBottom: PropTypes.number,
  marginLeft: PropTypes.number,
  marginRight: PropTypes.number,
  marginTop: PropTypes.number,
  maxHeight: PropTypes.number,
  minHeight: PropTypes.number,
  onBlur: PropTypes.func,
  onChangeText: PropTypes.func,
  paddingBottom: PropTypes.number,
  paddingLeft: PropTypes.number,
  paddingRight: PropTypes.number,
  paddingTop: PropTypes.number
}

export default class MyComponent extends React.Component {
  static propTypes = myTypes

  render () {
    return (
      <View></View>
    );
  }
}

How would you use myTypes as a type or helper to enable IDE auto-completion?

What I tried (in another file written in type-script as well) is below:

import MyComponent, { myTypes } from 'my-component';

const dark_theme_properties: myTypes = {
  activeColor: 'green'
};

But of course, that gives the 'myTypes' refers to a value, but is being used as a type here. ts(2749) error.


Edit: the question in the old title was "How to use a value as a type definition in typescript?", which thanks to the answers, I now know would be as simple as using typeof keyword, like:

const dark_theme_properties: typeof myTypes = {
  activeColor: 'green'
  // ...
};

Change height of tab bar of createMaterialTopTabNavigator from child screen

$
0
0

Is there any way to change the height of createMaterialTopTabNavigator from inside a child screen?

Basically - I have a request coming in from the server and in case there's no data - I need to show a placeholder screen (without the tab bar at the top). Is there any elegant way to do that? I just thought of doing 0 on contentContainerStyles height and it pretty much does the job done.


How to catch unused variables with husky precommit

$
0
0

In my react/typescript project, I used no-unused-variable rule with tslint. So if there are no unused variables or imports it will block the commit. Now it says that, it has been deprecated and use noUnusedLocals and **noUnusedParameters* in tsconfig file.

I used it like this.

"compilerOptions": {

    "target": "es6",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    // other rules

}

Now the unused variables are highlighted as warnings, but the precommit cannot catch them.

How can I fix this?

Hot reload crashing after changing sub-file of "folder import"

$
0
0

I have a project setup that looks like this (use this as an MVCE):

src/
  styles/
    index.ts
    common.ts
  app.tsx

The code in index.js looks like this:

import CommonStyles from "./common.ts";
export { CommonStyles };

common.ts looks like this:

import { StyleSheet } from "react-native";

const CommonStyles = StyleSheet.create({
    example: {
        width: "50%",
        height: "50%",
        backgroundColor: "red"
    }
});
export default CommonStyles;

From app.tsx i import these styles like this:

import React from "react";
import { View } from "react-native";
import { CommonStyles } from "./styles";

function App() {
    return (
        <View style={CommonStyles.example} />
    );
}

export default App;

The problem is that, when I change the style in common.ts (e.g. width: "75%") then save it, the app crashes with this error:

Requiring module "src\styles\index.ts", which threw an exception: TypeError: Attempting to change the getter of an unconfigurable property.

Versions

react-native-cli: 2.0.1   

"react": "16.8.6""react-native": "0.60.5"

I am not using expo.

P.S. I don't know what the JS term for "folder importing" like this is so feel free to edit title, thanks!

React native webview can not open links on android

$
0
0

React native webview component can not open links on Android, but on IOS it works fine, without any troubles. Nothing has happening on Android, after the pressing, no any errors. At the same time i tried to open links with react native hyperlink, and it works fine. Can you tell me please how can i solve it?

const IS_IOS = Platform.OS === 'ios';

const script = `
;(function() {
var wrapper = document.createElement("div");
wrapper.id = "height-wrapper";
while (document.body.firstChild) {
    wrapper.appendChild(document.body.firstChild);
}
document.body.appendChild(wrapper);
var i = 0;
function click(e) {
  e.preventDefault();
  window.postMessage(click, '*');
};
function updateHeight() {
    document.title = wrapper.scrollHeight;
    window.location.hash = ++i;
}
function linkProcessed() {
    var links = document.getElementsByTagName('a');
    for (var i = 0; i < links.length; i++) {
        links[i].onclick = function (e) {
            e.preventDefault();
            window.ReactNativeWebView.postMessage(e.currentTarget.getAttribute("href"), '*');
        }
    }

    var links = document.getElementsByTagName('img');
    for (var i = 0; i < links.length; i++) {
        links[i].onclick = function (e) {
            e.preventDefault();
            window.ReactNativeWebView.postMessage(e.currentTarget.getAttribute("src"), '*');
        }
    }
}
updateHeight();
setTimeout(linkProcessed, 1000);
window.addEventListener("load", function() {
    updateHeight();
    setTimeout(updateHeight, 1000);
});
window.addEventListener("resize", updateHeight);
}());
`;

const postMessage = `(function() {
    var originalPostMessage = window.postMessage;

    var patchedPostMessage = function(message, targetOrigin, transfer) {
        originalPostMessage(message, targetOrigin, transfer);
    };

    patchedPostMessage.toString = function() {
        return String(Object.hasOwnProperty).replace('hasOwnProperty', 'postMessage');
    };

    window.postMessage = patchedPostMessage;
})();`;

const style = `
<style>
body, html, #height-wrapper {
    margin: 0;
    padding: 0;
}
#height-wrapper {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
}
</style>
<script>
${script}
</script>
`;

const textStyleToCss = (textStyle: StyleProp<TextStyle>, styles?: StyleProp<ViewStyle>): string => {
  if (!textStyle) {
    return '';
  }

  const {
    fontSize,
    fontFamily,
    fontUrl,
    lineHeight,
    letterSpacing,
    color,
  } = StyleSheet.flatten(textStyle) as any;

  const {
    backgroundColor,
  } = StyleSheet.flatten(styles) as any;

  const css = IS_IOS ?
    `<style type="text/css">@font-face {font-family: MyFont; font-style: normal;
    font-weight: 400; src: local('${fontFamily}'), url('${fontUrl}');}
body,* {
    font-family: MyFont; font-size: ${fontSize}pt;text-align: left; line-height: ${lineHeight}pt; letter-spacing: ${letterSpacing}pt; color: ${color};
    background-color: ${backgroundColor};
}
img{height: auto;max-width: 100%;}
iframe {height: auto;max-width: 100%;}
div{height: auto;max-width: 100%;}
</style>` :

    `<style type="text/css">@font-face {font-family: MyFont; font-style: normal; 
     font-weight: 400; src: url("${fontUrl}");}
body,* {
    font-family: MyFont; font-size: ${fontSize}px;text-align: left; line-height: ${lineHeight}px; letter-spacing: ${letterSpacing}px; color: ${color};
    background-color: ${backgroundColor};
}
img{height: auto;max-width: 100%;}
iframe {height: auto;max-width: 100%;}
div{height: auto;max-width: 100%;}
   </style>`;

  return css;
};

const markdownLinksMap = (text: string) => {
  const markdownLinkReg = /\[([^\[\]]+)\]\(([^)]+)\)/img;

  text = text.replace(markdownLinkReg, (substring, ...args) => {
    const title = args[0];
    const url = args[1];
    const linkKey = `<a href="${url}">${title}</a>`;

    return linkKey;
  });

  return text;
};

const codeInject = (args: { html: string, textStyle?: StyleProp<TextStyle>, style?: StyleProp<ViewStyle> }): string => {
  const textWithoutMarkdown = markdownLinksMap(args.html);

  return (`
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    ${textStyleToCss(args.textStyle, args.style)}
</head>
<body>${'<div style="color: ' + args.textStyle!.color + '">' + textWithoutMarkdown + '</div>'}${style}</body> 
  `)
};

interface TextStyleProp extends TextStyle {
  fontSize: number;
  fontFamily: string;
  lineHeight: number;
  letterSpacing: number;
  color: string;
  fontUrl: string;
}

interface Props {
  html: string;
  navigateToWebview?: (url: string) => void;

  style?: StyleProp<ViewStyle>;
  textStyle?: StyleProp<TextStyleProp>;
}

interface State {
  correctHtml: string;
  height: number;
}

export class AutoHeightWebView extends React.Component<Props, State> {
  public static getDerivedStateFromProps(props: Props, state: State) {
    if (props.html) {
      const correctHtml = codeInject(props);

      return { correctHtml };
    }

    return null;
  }

  private webview: any;

  constructor(props: Props) {
    super(props);

    this.state = {
      correctHtml: codeInject(props),
      height: 120,
    };
  }

  public componentWillUnmount(): void {
    if (this.webview) {
      this.webview.stopLoading();
      this.webview = null;
    }
  }

  public render() {
    if (!(this.props.html && this.props.html.length > 0)) {
      return (<View />);
    } else {
      return (
        <View style={[SS.container, this.props.style]}>
          <WebView
            ref={this.setWebView}
            automaticallyAdjustContentInsets={true}
            source={{ html: this.state.correctHtml, baseUrl: '' }}
            onMessage={this.onMessage}
            javaScriptEnabled={true}
            injectedJavaScript={`${postMessage};document.body.scrollHeight;`}
            style={{ height: this.state.height }}
            onNavigationStateChange={this.onNavigationChange}
            domStorageEnabled={true}
            scalesPageToFit={Platform.select({ios: undefined, android: true})}
            startInLoadingState={true}
            scrollEnabled={true}
            showsHorizontalScrollIndicator={false}
            showsVerticalScrollIndicator={false}
            bounces={false}
            originWhitelist={['*']}
          />
        </View>
      );
    }
  }

  private onNavigationChange = (event: NavState): void => {
    if (event.title) {
      const htmlHeight = Number(event.title); //convert to number
      if (htmlHeight && this.state.height !== htmlHeight) {
        this.setState({ height: htmlHeight });
      }
    }
  }

  private onMessage = (event: NativeSyntheticEvent<WebViewMessageEventData>): void => {
    const url = event.nativeEvent.data;
    if (this.props.navigateToWebview) {
      this.props.navigateToWebview(url);
    } else {
      Linking.openURL(url);
    }
  }

  private setWebView = (webview: any): void => {
    this.webview = webview;
  };
}

const SS = EStyleSheet.create({
  container: { flex: 1, overflow: 'hidden' },
});

TypeScript not parsing react-native-web code

$
0
0

Already tried suggestions here and here with no luck

I have a project with a directory structure like this:

.
  - /app
  - /web

app is a react native app (created manually, not with create-react-native-app).

web is a react app created using create-react-app.

Both use TypeScript.

I'm trying to render a component from app in the web application using react-native-web, but TypeScript doesn't seem to be parsing the file as I get this error:

You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| 
> export type Props = {

Given that TypeScript is working fine within app and web independently, I'm not sure what I'm missing. One slight quirk of the project is that, because create-react-app doesn't allow relative imports from outside its own src folder, I've had to symlink app using npm link app in the web directory in order to import the app components.

Not sure if that's causing the problem, but I'm pretty stumped so any suggestions would be greatly appreciated.

Typescript: tabBarOptions from createBottomTabNavigator

$
0
0

I was building a react-native app via expo init via its 3rd option, which creates basic navigation template in Javascript. And recently I was trying out the Typescript with the existing template and try to convert those js code into typescript but cannot figure out why typescript raise errors on tabBarOptions.

The below is the partial code with slightly modifications from original(official) that has nothing to do with the type error. The code itself is perfectly runnable and the pattern appears in many SO questions about how to use tabBarOptions in createBottomTabNavigator correctly.

enter image description hereenter image description here

This is the typescript error. enter image description here

I also see the issue from github that layouts the component relationship.

https://github.com/react-navigation/tabs/issues/174

As far as I understand based on the link, the error shall not appear. I'm new to typescript so please don't judge me if I misunderstand any concept.

Viewing all 6202 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>