Material-ui: [TextField]は再レンダリングに集䞭できなくなりたす

䜜成日 2015幎06月08日  Â·  41コメント  Â·  ゜ヌス: mui-org/material-ui

フォヌカスがあったテキストフィヌルドがsetStateによっお再レンダリングされるず、フォヌカスが倱われたす。

question v0.x

最も参考になるコメント

@scotmatson少なくずも私の堎合、ラッパヌずしお持っおいるContainer = styled.divを通垞のスタむルなしコンポヌネントdivに倉換するず、問題が解決するこずを確認できたす。

線集
そしお、私もあなたの欲求䞍満を共有したす。 これらの2぀のラむブラリが完璧に連携しおいれば本圓に玠晎らしいでしょう。 この問題ず特異性の問題は、私がすぐに解決されるこずを望んでいる2぀のこずですが、私は圌らの時間をボランティアしおくれた人々に感謝しおいたす。

Edit2
私の堎合、問題の原因を発芋したした。renderメ゜ッドでスタむル付きコンポヌネントコンポヌネントを宣蚀したす。 これにより、すべおの再レンダリングでコンポヌネントが再䜜成され、Reactは再レンダリングの境界を越えおフォヌカスされた芁玠を远跡できたせんでした。 これはたた、私にずっお他のいく぀かの再レンダリングの問題に぀ながりたした。

スタむル付きコンポヌネントの宣蚀をすべおコンポヌネントの倖郚に移動するこずで、フォヌカスが倱われる問題が解決したした。 おそらく初心者の間違いですが、ここでは誰もそれに぀いお蚀及しおいないので、私は戻っお報告するず思いたした。

党おのコメント41件

+1

Textfieldsをスムヌズに機胜させるには、defaultValueでonBlurむベントを䜿甚する必芁がありたす。

誰かがこれを機胜させるための回避策がありたすか

これはもう問題ではないず思いたす。 以䞋のコヌドを参照しおください。

//taken from examples/webpack-example

/** In this file, we create a React component which incorporates components provided by material-ui */

const React = require('react');
const RaisedButton = require('material-ui/lib/raised-button');
const TextField = require('material-ui/lib/text-field');
const Dialog = require('material-ui/lib/dialog');
const ThemeManager = require('material-ui/lib/styles/theme-manager');
const LightRawTheme = require('material-ui/lib/styles/raw-themes/light-raw-theme');
const Colors = require('material-ui/lib/styles/colors');

const Main = React.createClass({

  childContextTypes: {
    muiTheme: React.PropTypes.object,
  },

  getInitialState () {
    return {
      muiTheme: ThemeManager.getMuiTheme(LightRawTheme),
      counter: 0,
    };
  },

  getChildContext() {
    return {
      muiTheme: this.state.muiTheme,
    };
  },

  componentWillMount() {
    let newMuiTheme = ThemeManager.modifyRawThemePalette(this.state.muiTheme, {
      accent1Color: Colors.deepOrange500,
    });

    this.setState({muiTheme: newMuiTheme});
  },

  componentDidMount() {
    this.refs.textField.focus();
  },

  render() {

    console.log(this.state.counter);

    let containerStyle = {
      textAlign: 'center',
      paddingTop: '200px',
    };

    let standardActions = [
      { text: 'Okay' },
    ];

    return (
      <div style={containerStyle}>
        <Dialog
          title="Super Secret Password"
          actions={standardActions}
          ref="superSecretPasswordDialog">
          1-2-3-4-5
        </Dialog>

        <h1>material-ui</h1>
        <h2>example project</h2>

        <TextField ref="textField" onChange = {this._incrementStateCounter}/>
        <RaisedButton label="Super Secret Password" primary={true} onTouchTap={this._handleTouchTap} />

      </div>
    );
  },

  _handleTouchTap() {
    this.refs.superSecretPasswordDialog.show();
  },

  _incrementStateCounter () {
    this.setState({counter: this.state.counter + 1});
  },

});

module.exports = Main;


これが動䜜䞭のアプリですTextField入力が倉曎されるず曎新された状態がコン゜ヌルに蚘録されたす。 TextFieldがフォヌカスを保持しおいるこずがわかりたす。

4uo63bzhmj

私はただこれを取埗したす。 @ shaurya947の䟋では、TextFieldに初期倀プロパティがなかったため、バグを再珟したせんでした。
䜿甚を再珟する
<TextField ref="textField" value={this.state.valueToBeEdited} onChange = {this._incrementStateCounter}/>

たたは

<TextField ref="textField" defaultValue={this.state.valueToBeEdited} onChange = {this._incrementStateCounter}/>

たた、この問題の回垰ず思われるものも芋おいたす。 私のTextFieldsは再レンダリングぞの焊点を倱っおいたす。 私は蚭定しおいたすvalueの小道具TextField 、それが制埡コンポヌネントであるので、。

コン゜ヌルに新しい譊告が衚瀺されたす。「TextFieldは、制埡察象のテキスト型の制埡されおいない入力を倉曎しおいたす」。 以前にそれを芋たのを芚えおいたせん、それがここに関連しおいるかどうかはわかりたせん。 TextField最初の文字を入力するず、譊告が衚瀺されたす。

少しデバッグするず、䜕かがTextFieldフォヌカスを倱っおいるようです。 内郚onBlurハンドラヌが呌び出され、 TextFieldのisFocused内郚状態がfalseに切り替わりたす。 onBlurハンドラヌの間にdocument.activeElementをログに蚘録するずどのコンポヌネントがフォヌカスを盗んだかを刀別するため、ドキュメントのルヌト本文がログに蚘録されたす。

がかしむベントの゜ヌスがアプリの他の堎所のMenu内の最初のMenuItemであるず刀断するこずで、これをさらに絞り蟌むこずができたした。 disableAutoFocusプロパティをtrue 、問題が解決したした。 これが他の誰かに圹立぀こずを願っおいたす。

これをキャプチャするために別の問題を開きたした4387。

これはただ問題であるこずが確認できたす...

非垞に単玔なログむンフォヌムで衚瀺したす-これをreduxフォヌムず組み合わせお䜿甚​​しおいたす。フォヌムを操䜜するず、再レンダリングreduxフォヌムの甚語でフィヌルドに觊れたが発生し、フォヌカスが倱われたす。

回避策ずしお、゚ラヌ状態に倉化があった堎合にのみ実際のフォヌムを再レンダリングしたす。

selectable=trueずしお蚭定されたTable内にTextField配眮するこずで、この問題を簡単に再珟できたす。 あなたはそれを線集を開始するには、テキストフィヌルドをクリックするたびに、行が私はいく぀か掚枬するように、フォヌカスを取埗し、その背景色を倉曎したすpropsラむンのは次のように蚭定されるこずがありたすselected=trueので、再レンダリングをトリガヌするず、フォヌカスが倱われたす...

したがっお、基本的にselectable Table内でTextField䜿甚するこずはできたせん。ずにかく、それが優れたUXプラクティスであるかどうかはわかりたせんが、それでも:)

私たちのプロゞェクトでは、再生装眮をプッシュしようず詊みるこずができるこずに気づきたした。

これに察する回避策はありたすか たた、テヌブル内の通垞の入力テキスト領域を䜿甚する堎合にも泚意しおください。

@ dalexander01 「解決策」が芋぀かりたしたが、md入力コンポヌネントを䜿甚しおいないずきに同じ問題が発生しおいたため、非垞にredux圢匏に固有のようです。 圹に立ったらスニペットを投皿できたす

@deycegしおください、それは傷぀くこずはできたせん😄。 <Dialog/>ず<TextField/>この組み合わせで、この問題が発生するだけです。

      <Dialog
        open={this.props.showDialog}
        title={'New ' + this.props.type}
        autoScrollBodyContent={true}
        actions={actions}
        bodyStyle={styles.dialogContent}
      >
        <SelectField
          name='sub_type'
          value={this.props.top_card.sub_type}
          onChange={(e, k, payload) => this.props.topCardSelectChange('sub_type', payload)}
          floatingLabelText='Type'
        >
          {menuItemsJSX}
        </SelectField>
        <TextField
          name='title'
          className='story-title'
          value={this.props.top_card.title}
          onChange={this.props.topCardChange}
          floatingLabelText='Title'
          fullWidth={true}
          multiLine={true}
          style={styles.title}
        />
        <TextField />
      </Dialog>

私の堎合は解決したした。そのテキストフィヌルドに䞀意のIDを指定する必芁がありたす。
..。
ただし、再レンダリング埌にIDを倉曎するこずはできたせん。 このようにしお、Reactはどの芁玠がフォヌカスされおいるかどうかを远跡できたす。
PS myArray.mapを介しおレンダリングされる配列にテキストフィヌルドがあり、再レンダリングするずきに同じキヌを指定する必芁がありたす。

線集myArrayの「キヌ」を再レンダリング間で同じにするだけで、問題が解決したした。
テキストフィヌルドIDがshortid.generateに倉曎されたした。

    params.map(function(p,i){
        return(
           <div key={i}>              <--- this will always be the same for this particular row.
               <div className='param-inner'>
                   <TextField id={shortid.generate()} value = {p.value} onChange={this.updateParam.bind(this,i)}/>               <-- id here can be random, but it is necessary to avoid browser warning "we don't have enough information..."
                   </div>
               <div className='param-inner'>{p.unit}</div>
           </div>
        )
    }.bind(this));

誰かがこの問題の回避策を芋぀けるこずができたしたか refsを䜿甚せずに これは、 onChangeず、 value小道具を状態キヌに蚭定しお入力のフォヌカスを緩めるこずの組み合わせのようです。

私も次の問題を抱えおいたしたが、内郚でDropdownMenu https://github.com/callemall/material-ui/blob/ccf712c5733508784cd709c18c29059542d6aad1/src/SelectField/SelectFieldを呌び出しおいる堎合は、SelectField実装を䜿甚するこずで解決したした

そのため、DropDownMenuを远加する必芁もありたす。これは、内郚でコンポヌネントをメニュヌにラップしおいたす。disableAutoFocusを远加しお、TextFieldが次のようにフォヌカスを維持できるようにしたした。

たぶん、SelectFieldからDropDownMenuコンポヌネントを公開し、小道具でオヌトフォヌカスを無効にするこずができたす。

out

これに苊劎しおいお䜕かを機胜させたいだけの人のための1぀の回避策ですが、状況によっおは適甚できない可胜性があり、問題が発生する可胜性がありたす私自身は完党にはわかりたせんがむンスタンスで倉数を䜿甚するこずです状態より。 したがっお、 this.state.value代わりに、 onChangeが曎新されるのはthis.value onChangeなりたす。 コンポヌネントにはvalue小道具はありたせん。 次に、 onChangeハンドラヌで、 e.target.valueたす。

むンスタンスの倉数ず状態の違いは、むンスタンス倉数が再レンダリングをトリガヌしないこずだけです。 他にも理由があるかもしれたせんが、他の人がこれで私のたるみを捕たえるこずを願っおいたす。

それでもこの゚ラヌが発生したす。 回避策はありたすか

私が芋぀けた回避策は、shouldComponentUpdate関数をコンポヌネントにオヌバヌラむドし、テキストフィヌルドで䜿甚される状態倀を倉曎するずfalseを返すこずでした。

`shouldComponentUpdate(nextProps, nextState) {    

    if(nextState.email != this.state.email) {  

      return false;  

    }

    else if(nextState.password != this.state.password) {  

      return false;  

    }  
    else return true;  
    }

`

この方法でそれを行うず、私の問題が修正されたした。 問題は、状態が倉化するたびにコンポヌネントがレンダリングされ、フォヌカスがリセットされるこずにあるようです。 したがっお、䞊蚘の関数を䜿甚しお、onChangeむベントを実行しお状態倀を蚭定するずきにレンダリングを無効にするず、コンポヌネントはリロヌドされたせん。

@ Aspintyl000これは機胜したす...やや。 'value' propを䜿甚しおテキストフィヌルドの倀を蚭定し、そのpropを 'this.state.value'に蚭定するず、䜕も衚瀺されたせん。 しかし、それを取り陀くず、うたくいくようです。

テヌブルの行でテキストフィヌルドを䜿甚しおいたすが、これは問題です:(進捗状況はありたすか

Psid.txt

私も同じ゚ラヌが発生しおいたした。 しかし、componentDidMountを䜿甚した埌{
this.refs.textField.focus;
}
フォヌカスを倱うこずはありたせん。 ただし、入力倀は衚瀺されたせん。

私が远加しようずしたした<TextField />で<Table /> 。 䞊蚘の状況のように、私は入力に焊点を合わせるこずができたせん。
私の解決策 onClickむベントをに远加したす 、クリックするず、テヌブルのselectable=false蚭定したす。 入力操䜜の埌、 onBlueむベントを䜿甚しお、テヌブルのselectable=trueを蚭定したす。

かなり䞍快な行動。

2぀の入力ボックスをスタむル付きコンポヌネントでラップした埌、これを経隓したした。 倖偎のdivは完党に動䜜を壊したした。 これは、このラむブラリの蚭蚈におけるひどい欠陥です。

したがっお、これはかなりひどい回避策ですが、䞻に次のように機胜したす。

「」
onSomeValueChanged =むベント=> {
this.props.someValueChangedevent.target.value;

const { target } = event;
setTimeout(() => {
  target.focus();
}, 10);

};
「」

ええ、きれいではありたせん...

@scotmatson 「かなり䞍快な振る舞い...このラむブラリの蚭蚈におけるひどい欠陥」。 これはボランティアによっお䜜られたフリヌ゜フトりェアです...しかしstyled-componentsずの関係をよく理解しおください。

@scotmatson少なくずも私の堎合、ラッパヌずしお持っおいるContainer = styled.divを通垞のスタむルなしコンポヌネントdivに倉換するず、問題が解決するこずを確認できたす。

線集
そしお、私もあなたの欲求䞍満を共有したす。 これらの2぀のラむブラリが完璧に連携しおいれば本圓に玠晎らしいでしょう。 この問題ず特異性の問題は、私がすぐに解決されるこずを望んでいる2぀のこずですが、私は圌らの時間をボランティアしおくれた人々に感謝しおいたす。

Edit2
私の堎合、問題の原因を発芋したした。renderメ゜ッドでスタむル付きコンポヌネントコンポヌネントを宣蚀したす。 これにより、すべおの再レンダリングでコンポヌネントが再䜜成され、Reactは再レンダリングの境界を越えおフォヌカスされた芁玠を远跡できたせんでした。 これはたた、私にずっお他のいく぀かの再レンダリングの問題に぀ながりたした。

スタむル付きコンポヌネントの宣蚀をすべおコンポヌネントの倖郚に移動するこずで、フォヌカスが倱われる問題が解決したした。 おそらく初心者の間違いですが、ここでは誰もそれに぀いお蚀及しおいないので、私は戻っお報告するず思いたした。

私が抱えおいるず思われる問題は、TextFieldsたたはInputがobject.map内にレンダリングされおいるずきは垞にフォヌカスが倚いこずです。 マップ倖のTextFieldsは完党に機胜しおいたす。 小道具などが足りたせんか 私は完党に倱われおいたす

私はこのスレッドで提案されおいるほずんどすべおの解決策を運がなくお詊したした。

倧たかな構造はこちら

メむンファむル

...
    function Steps(props) {
      const { steps } = props;
      if(steps) {
        return steps.map((step, index) => (
          <div key={(step.order === '' ? index : step.order)}>
            <NewUxCard step={step} index={index} onChange={props.onChange} 
              onChangeCard={props.onChangeCard} onParamChange={props.onParamChange}/>
          </div>
        ));
      }
    }  

<div>
  <TextField/> //working
  <Steps steps={this.props.ux.steps} onChange={this.onChange} 
              onChangeCard={this.handleChangeCard} onParamChange={this.handleParamChange} /> 
</div>

NewUxCard

...
<div>
  <TextField type="text" fullWidth id={"qq"+this.props.index} label="Name" 
                    value={this.props.step.name} onChange={this.props.onChangeCard('name', this.props.index)} margin="normal" /> //not working - loses focus on each key stroke
</div>

Redux-Reactを䜿甚しおいるので、状態倉化はinput-> action-> reducerを経由するこずに泚意しおください。

䜕か案は ありがずう

線集1
問題をさらに調査し、タグの䜜成に䜿甚される反応関数Stepspropsを削陀するこずで、問題を絞り蟌んで解決したした。この堎合。

だから以前は、構造は->関数Stepsprops->マッピングクラス。 だから今、私は関数䞭間の人を削陀し、Constステップ->マッピングクラスだけを削陀したした。 なぜこれが機胜しおいるのかおそらくいく぀かの小道具が無芖されおいたのかに぀いお掚枬するこずしかできたせんが、それは私のケヌスを解決したした。

@piltsen .map() TextFieldsをレンダリングしおいるずきにv1.5.0でこの問題が発生したした-入力ず同じ倀であるTextFieldキヌに絞り蟌んだため、倉曎するずTextFieldがマりントされる可胜性がありたした再びそしお焊点を倱いたす。 それがあなたに圹立぀かどうかはわかりたせん-私は今たでにあなたがそれを分類したず確信しおいたすが

これは、レンダヌプロップを䜿甚した堎合の症状でもありたす。 のようなこずをする

<HigherOrderComponent
    render={hocProps => <TextField value={...} onChange={...} />
/>

この動䜜を匕き起こす可胜性がありたす。 修正するには、蚭蚈で蚱可されおいる堎合は、代わりにフラグメントを枡したす。

<HigherOrderComponentThatDoesntPassOwnState
    component={<TextField  {...this.props}/>}
/>

私の堎合、フォヌカスが倱われたわけではないようですが、カヌ゜ルがTextFieldから消えたす。 document.activeElementがTextFieldず等しいこずを確認できたす。キヌボヌドコマンドずマりスホむヌルを䜿甚しお倀タむプ番号を倉曎できたすが、すべおのタむプレデュヌサヌがレンダリングを実行し、カヌ゜ルが倱われたす。

次に、レンダリングの䞊で、idでTextFieldを怜玢し、

MyTextField.blur();
MyTextField.focus();

、それは圹に立たない。 しかし、タむムアりトを䜿甚しおfocusを䜜成するず、機胜しおいるように芋えたす。

線集
ええず、HOCの内郚ではただ機胜しおいないので、ずにかくそれを抌し䞊げる必芁があるようです。

@ younes0私もそれを修正するこずを確認できたす。 私の堎合、いく぀かの䞀般的な小道具が蚭定されたTextFieldを返し、残りの小道具をその䞊に広げるヘルパヌステヌトレスコンポヌネントがあったので、 classNameやvariantなどを指定する必芁はありたせんvariant耇数回。 フォヌムに倉曎が加えられるずすぐにテキストフィヌルドのフォヌカスが倱われ、ヘルパヌ関数を削陀しお、生のTextField䜕床も䜕床も修正したした。

これを再開できたすか、それずも新しい問題を提出する必芁がありたすか

私はただこの問題を抱えおいたす、私は3.2.0を䜿甚しおいたす

@OmarDavilaP耇補で新しい問題を䜜成できたすか

私の堎合は解決したした。そのテキストフィヌルドに䞀意のIDを指定する必芁がありたす。
..。
ただし、再レンダリング埌にIDを倉曎するこずはできたせん。 このようにしお、Reactはどの芁玠がフォヌカスされおいるかどうかを远跡できたす。
PS myArray.mapを介しおレンダリングされる配列にテキストフィヌルドがあり、再レンダリングするずきに同じキヌを指定する必芁がありたす。

線集myArrayの「キヌ」を再レンダリング間で同じにするだけで、問題が解決したした。
テキストフィヌルドIDがshortid.generateに倉曎されたした。

    params.map(function(p,i){
        return(
           <div key={i}>              <--- this will always be the same for this particular row.
               <div className='param-inner'>
                   <TextField id={shortid.generate()} value = {p.value} onChange={this.updateParam.bind(this,i)}/>               <-- id here can be random, but it is necessary to avoid browser warning "we don't have enough information..."
                   </div>
               <div className='param-inner'>{p.unit}</div>
           </div>
        )
    }.bind(this));

うん、それは私の堎合の問題を解決したす、基本的に私は䜿甚しおいたした

<NewTextField key={user.id+Math.random()}>
私はそれを次のように眮き換えたした

<NewTextField key={user.id}>
したがっお、コンポヌネントを再レンダリングするたびにランダムなキヌを生成するのは悪い習慣のようです。

私にずっおの問題は、TextFieldのラッパヌ関数を䜜成したこずでしたが、コンポヌネント関数内でその関数を宣蚀したした。関数の倖に移動するず、すべおが期埅どおりに機胜したした。

sendboxサンプルを䜜成したしたhttps://codesandbox.io/s/material-demo-msbxl?fontsize=14&hidenavigation=1&theme=dark

条件付きレンダリングでこの問題が発生しおいたす。 レンダリングには、.jsファむルのさたざたなコンポヌネントを返すjavascriptオブゞェクトがありたす。 正しく説明しおいたせん、ごめんなさい。 修正したら、芚えおいればこの投皿を線集したす。

線集むェヌむ、私はそれを修正したした 条件付きでレンダリングする方法は、衚瀺されおいない堎合でも各コンポヌネントをレンダリングするこずだったず思いたす。 ロゞックをレンダリングの倖に移動したしたが、珟圚は正垞に機胜しおいるようです。 叀いコヌドは次のずおりです。

線集私はこのこずでスタむリングするこずができないので気にしないでください。

私は今日この問題に遭遇し、数時間頭をぶ぀けたした。 私の堎合、間違っおいたのは、 TextFieldをステヌトレスコンポヌネントでラップしお、ペヌゞをより適切に敎理するこずでしたデヌタが読み蟌たれおいる堎合などはレンダリングしないでくださいが、 useStateを残したした芪コンポヌネントのTextFieldを制埡するuseStateコヌルバック。

埌䞖のために、ここに私の愚かさを再珟するための小さなコヌドサンドボックスリンクがありたす

ここでの問題は、 TextFieldラップするカスタムコンポヌネントをどのように䜜成するかずいうこずです。 このバグでは、HOCずcreateElement䞡方が発生しおいるようです。

  const MyField= ({ name, ...props }) => (
    <TextField
      fullWidth
      variant="outlined"
      size="small"
      name={name}
      {...props}
    />
  );
  const MyField= ({ name, ...rest }) => {
    return React.createElement(TextField, {
      fullWidth: true,
      variant: "outlined",
      size: "small",
      name: name,
      {...rest}
    });
  };

気にしないでください。䞊蚘のアプロヌチは問題なく機胜したす。芪コンポヌネント内でカスタムコンポヌネントが定矩されおいるこずに気づき、問題が発生したした。 芪スコヌプの倖に移動するず本来あるべきように正垞に動䜜したす-以前のサンドボックスを曎新しお、正しいアプロヌチを瀺したした https 

私にずっおの問題は、TextFieldのラッパヌ関数を䜜成したこずでしたが、コンポヌネント関数内でその関数を宣蚀したした。関数の倖に移動するず、すべおが期埅どおりに機胜したした。

sendboxサンプルを䜜成したしたhttps://codesandbox.io/s/material-demo-msbxl?fontsize=14&hidenavigation=1&theme=dark

これが私の問題でした。 ありがずうございたした

気にしないでください。䞊蚘のアプロヌチは問題なく機胜したす。芪コンポヌネント内でカスタムコンポヌネントが定矩されおいるこずに気づき、問題が発生したした。 芪スコヌプの倖に移動するず本来あるべきように正垞に動䜜したす-以前のサンドボックスを曎新しお、正しいアプロヌチを瀺したした https 

ありがずうございたした。 これはうたくいきたした

私にずっおの問題は、TextFieldのラッパヌ関数を䜜成したこずでしたが、コンポヌネント関数内でその関数を宣蚀したした。関数の倖に移動するず、すべおが期埅どおりに機胜したした。

sendboxサンプルを䜜成したしたhttps://codesandbox.io/s/material-demo-msbxl?fontsize=14&hidenavigation=1&theme=dark

@ fleischman718これを理解しおくれおありがずう 芪コンポヌネントの定矩内のTextFieldのラッピングコンポヌネント関数を削陀するず、問題が修正されたした。

サンドボックスで䜕が起こっおいるのかを理解するのに1秒かかったので、以䞋に芁玄を瀺したす。

import { TextField } from '@material-ui/core';

const ParentComponent = () => {

  // DON'T DO THIS!!!
  // fix issue by moving this component definition outside of the ParentComponent
  // or assign the TextField to a variable instead
  const TextFieldWrapper = () => (
    <TextField />
  );

  return (
    <div>
      <TextFieldWrapper />
    </div>
  )
}
このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡