Vajíčková mánie Vajíčková mánie
Od 15. do 21.4. slevy 20 až 80% v sekci C/C++. Když ne teď, tak kdy?
Vyšlehej si extra vědomosti! Až 100% bodů na prémiový obsah zdarma! Více zde
Avatar
Adam Gajdečka:30. ledna 23:09

Potřebuji zavolat focus z rodičovské komponenty. Problémem je, že používám https://www.npmjs.com/…t-input-mask

a metoda focus() je dostupná ne přes ref, ale přes inputRef. Když zavolám focus(); tak objekt input je null. Stejným způsobem mám napsané ostatní podobné komponenty, ale tam je to vždy přes ref a funguje to.

Díky

React 16.7 + Typescript

Zkusil jsem:

import * as React from 'react';
import InputMask, { ReactInputMask } from 'react-input-mask';
import IInputField from '../Input/IInputField';

interface IProps {
    required?: boolean;
    icon?: string;
    placeholder?: string;
    label: string;
    value: string;
    onChange: Function,
}

interface IState {
    errors: Array<string>,
}

export default class InputTelephone extends React.Component<IProps, IState> implements IInputField{

    private input: React.RefObject<HTMLInputElement>;

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

        this.input = React.createRef();

        this.state = {
            errors: [],
        };
    }


    focus() {
        this.input.current.focus(); //toto je celé NULL
    }

    isValid() {
        return this.getErrors().length == 0;
    }


    getErrors(value = this.props.value) {
        let errors = [];
        if (this.props.required && value.includes("_")) {
            errors.push("Toto pole je povinné");
        }
        return errors;
    }

    validate(value = this.props.value) {
        this.setState({
            errors: this.getErrors(value),
        })
    }

    handleChange(e: any) {
        this.validate(e.target.value);
        this.props.onChange(e.target.value);
    }

    renderError() {
        if (this.state.errors.length == 0) { return; }

        return (
            <ul className="parsley-errors-list filled" id="parsley-id-5">
                <li className="parsley-required">{this.state.errors[0]}</li>
            </ul>
        )
    }

    renderInput() {
        return (
            <InputMask
                inputRef={this.input}
                mask="+(999) 999 999 999"
                className={`form-control ${this.state.errors.length === 0 ? '' : 'parsley-error'}`}
                placeholder={this.props.placeholder}
                value={this.props.value}
                onChange={this.handleChange.bind(this)}
            />
        );
    }

    renderLabel() {
        return (
            <label className="form-control-label">
                {this.props.label} {this.props.required ? <span className="tx-danger">*</span> : null}
            </label>
        );
    }

    render() {
        if (this.props.icon) {
            return this.renderWithIcon();
        }

        return (
            <div className="form-group">
                {this.renderLabel()}
                {this.renderInput()}
                {this.renderError()}
            </div>
        );
    }

    renderWithIcon() {
        return (
            <div>
                {this.renderLabel()}
                <div className="input-group">
                    <div className="input-group-prepend">
                        <span className="input-group-text">
                            <i className="icon ion-email tx-16 lh-0 op-6"></i></span>
                    </div>
                    {this.renderInput()}
                </div>
                {this.renderError()}
            </div>
        );
    }
}

Chci docílit: Zavolat focus()

Zapomněl jsem napsat celý nadpis, nejde již upravit. :-( To se omlouvám

Editováno 30. ledna 23:12
 
Odpovědět 30. ledna 23:09
Avatar
Patrik Smělý
Tým ITnetwork
Avatar
Odpovídá na Adam Gajdečka
Patrik Smělý:31. ledna 0:36

Ahoj, vypadá to že ten NPM balíček nepodporuje "moderní" implementaci referencí v Reactu. inputRef je totiž prop do kterého musíš dát funkci, která v prvním argumentu obdrží právě danou referenci přímo na input. Viz: zde.

v konstruktoru přepiš

this.input = React.createRef();

Na

this.input = null;

A finálně u InputMask komponentu dej do propu inputRef funkci, která nastaví input na tu referenci co přijde v prvním argumentu. Třeba takhle:

inputRef={r => this.input = r}

Ukázka

Editováno 31. ledna 0:37
Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
 
Nahoru Odpovědět 31. ledna 0:36
Avatar
Patrik Smělý
Tým ITnetwork
Avatar
Patrik Smělý:31. ledna 0:45

Jo a focus voláš bez current, jelikož je to přímo cesta k té referenci. Takže jen

this.input.focus();
 
Nahoru Odpovědět 31. ledna 0:45
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:31. ledna 7:52

google = focus input React example
-> https://stackoverflow.com/…after-render

class App extends React.Component{
  componentDidMount(){
    this.nameInput.focus();
  }
  render() {
    return(
      <div>
        <input
          defaultValue="Won't focus"
        />
        <input
          ref={(input) => { this.nameInput = input; }}
          defaultValue="will focus"
        />
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('app'));

<input autoFocus type="text" />


componentDidMount() {
this.refs.lin­kInput.focus()
}


render: function() {
  return (
    <TextInput
      ref={function(input) {
        if (input != null) {
          input.focus();
        }
      }} />
    );
  },

-----

render: function() {
  return <TextInput ref={(c) => this._input = c} />;
},
componentDidMount: function() {
  this._input.focus();
},

---

<input ref={ function(component){ React.findDOMNode(component).focus();} } />

---

const focusUsernameInputField = input => {
  if (input) {
    setTimeout(() => {input.focus()}, 100);
  }
};

return (
  <TextField
    hintText="Username"
    floatingLabelText="Username"
    ref={focusUsernameInputField}
  />
);
Editováno 31. ledna 7:53
 
Nahoru Odpovědět  -1 31. ledna 7:52
Avatar
Odpovídá na Patrik Smělý
Adam Gajdečka:31. ledna 8:37

díky moc. Teprve s Reactem začínám :-) Funguje to skvěle, jen nevím, jaký datový typ tomu přiřadit. Bez něj mi to nejde, tak jsem dal any.

private input:any;
 
Nahoru Odpovědět 31. ledna 8:37
Avatar
Patrik Smělý
Tým ITnetwork
Avatar
Odpovídá na Adam Gajdečka
Patrik Smělý:31. ledna 9:46

Můžeš tomu dát přímo typ HTMLInputElement.

 
Nahoru Odpovědět 31. ledna 9:46
Avatar
 
Nahoru Odpovědět  +1 31. ledna 9:48
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 7 zpráv z 7.