2017-08-14 7 views
14

CSSトランジションを使用してリアクションアプリを作成しました。しかし、これらのトランジションは、一部のコンポーネントでは正しく機能しません。 my appでは、上に移動するコンポーネントだけがうまく動作し、下に移動するコンポーネントは、アニメーションなしで即座に動きます。 UPDATEDリアクションCSSが正しく動作しない

div.canvas { 
    position: absolute; 
    top: 90px; 
    left: 60px; 
    width: 640px; 
    height: 480px; 
    border: 1px solid #999; 
    background: white; 

} 

div.canvas-rect { 
    position: relative; 
    margin-left: 20px; 
    margin-top: 10px; 
    height: 20px; 
    background: green; 

    transition: all 1s linear; 
    -moz-transition: all 1s linear; /* Firefox 4 */ 
    -webkit-transition: all 1s linear; /* Safari 和 Chrome */ 
    -o-transition: all 1s linear; /* Opera */ 

} 

::ここでは(私はアニメーションでそれらの両方を移動したい)

は私が使用CSSです

私はまた、問題を表示するcodepen.io projectを構築しました。このデモプロジェクトの完全なコードがあります。

私は、これらのコンポーネントを再作成または更新されているかどうかを示すためにcomponentDidUpdatecomponentDidMountcomponentWillUnmount方法にログエントリを追加しようとしました、それは彼らがすべての更新(再作成されない、または削除)されていることを毎秒を示し。

+0

は、あなたが問題を再現する作業コードスニペットを投稿する必要があり – LGSon

+0

そのため@LGSon申し訳ありませんが、私はcodepen.ioプロジェクトを構築してきましたすぐに質問が更新されます。 – cmal

+0

単に 'top'値の一部を入れ替えるだけで、それらは下にもアニメーションを開始します。私はそれらの値がどのようにアイテム上で切り替えられているかをチェックする必要があると思います。 https://codepen.io/anon/pen/ZJazQa ...また、CSS – LGSon

答えて

11

私もこの問題を抱えているので奨励金を払った後、私は最終的に問題と思われるものを見つけました。

絶対位置(またはあなたの場合のような相対位置)を使用しているときに、毎回リスト全体を再レンダリングすると、ReactはDOMの要素を並べ替えます(言い換えれば、再作成されたばかりです)。しかし、これはトランジションの問題を引き起こします...明らかに、トランジションが実行されている間に要素を移動すると、アニメーションをカットすることになります。

ポジションアブソリュートを使用する場合は、要素のコンテナ(この場合はdivのみ)をレンダリングし、新しいオーダーに基づいて内部コンテンツを変更することが重要です。要素を追加する必要がある場合は、最後に追加してください。

私は自分の言いたいことが反映されるようにコードを修正しました。私はちょうど4つのアドホック・ディビジョンを作成したので、私の例は非常に馬鹿ですが、必要な数のコンテナを作成しますが、毎回それらを再作成するマップを使用しないでください。

https://codepen.io/damianmr/pen/boEmmy?editors=0110

const ArrList = ({ 
    arr 
}) => { 
    return (
    <div style={{position: 'relative'}}> 
     <div className={`element element-${arr[0]} index-${arr[0]}`}>{arr[0]}</div> 
     <div className={`element element-${arr[1]} index-${arr[1]}`}>{arr[1]}</div> 
     <div className={`element element-${arr[2]} index-${arr[2]}`}>{arr[2]}</div> 
     <div className={`element element-${arr[3]} index-${arr[3]}`}>{arr[3]}</div> 
    </div> 
); 
} 

ので、問題は第二の容器、第一の容器はあなたのデータの最初の要素をレンダリングするように、あなたがコンテナの静的リストを作成する方法と、あなたはそのリストを反復処理する方法、基本的です2番目の要素など

私はこの問題が私を狂ってしまうのを助けてくれることを願っています! :)

+1

私はこの回答を何千回も投票できたらいいと思っています...ありがとう! – MarkoCen

+0

あなたは大歓迎です! @MarkoCen – damianmr

1

仮想DOMから要素を削除する場合、反応はその内容を更新するため、アニメーションは表示されません。あなたができることは、react-transition-groupを使用するか、イベントが呼び出されるとDOMを更新する前にx ms待機するか、可視性を使用してDOMから完全に削除するのではなく、表示と非表示を切り替えます。

+0

おかげで接頭辞の後に非接頭辞プロパティは常にあるべき、注意してください。しかし、要素はV-DOMから削除されておらず、ただコンポーネントを更新しました。私はそれについての質問を更新しました。 – cmal

1

毎回DOM要素を再作成しました。
collectキー値を定義する必要があります。 キー値'' + el'' + indexに変更しました。

<div key={'' + index} className={'element element-' + el + ' index-' + index} > 

ちょうどのみ:)

1

あなたがキーとしてindexを使用して反応だますことができcssプロパティを変更します。あなたは位置(インデックス)と終了位置(EL)を開始し、約el、およびindexを考える場合、要素は、遷移の終わりまでに、旧端位置に移動した、そしてそれがあるときで、それが新たなスタートに引き継がれています新しい設定と一致するように位置と(インデックス)が切り替わります。あなたが反応するの要素にkeyを設定すると、それは同じ要素であるとして、仮想DOMは常にそれを解釈するためです。そしてそれのために、あなたは一般的に "id"としてインデックスを設定するのが正しいです。

私はインデックス/ ELを切り替える(絶対に要素の位置を設定する)ことにより、実施例を行いました。私達はちょうど2 CSSルールをデバッグすることはできません

const {combineReducers, createStore} = Redux; 
 
const { Provider, connect } = ReactRedux; 
 

 
const ArrList = ({ 
 
    arr 
 
}) => (
 
    <div>{ 
 
    arr.map((el, index)=> 
 
      <div 
 
      key={""+index} 
 
      className={`element element-${el}` + ` index-${el}`} 
 
      > 
 
      {el} 
 
      </div>) } 
 
    </div> 
 
) 
 
     
 
const mapStateToArrList = (state) => { 
 
    return { 
 
    arr: state.appReducer.arr 
 
    } 
 
}; 
 

 
const App = connect(mapStateToArrList, null)(ArrList); 
 

 
const initialState = { 
 
    arr: [1, 2, 3, 4] 
 
} 
 

 
const appReducer = (state = initialState, action) => { 
 
    switch(action.type) { 
 
    case "tick": 
 
     return { 
 
     ...state, 
 
     arr: _.shuffle(state.arr) 
 
     } 
 
    default: 
 
     return state 
 
    } 
 
} 
 

 
const reducer = combineReducers({ 
 
    appReducer 
 
}) 
 

 

 
const store = createStore(reducer) 
 

 
ReactDOM.render(
 
    <Provider store={store}> 
 
    <App /> 
 
    </Provider>, 
 
    document.getElementById('root') 
 
) 
 

 
const dispatcher =() => { 
 
    store.dispatch({ 
 
    type: "tick" 
 
    }) 
 
    setTimeout(dispatcher, 1000) 
 
} 
 

 
dispatcher()
.element { 
 
    position: absolute; 
 
    height: 20px; 
 
    background: green; 
 
    margin-left: 20px; 
 
    margin-top: 20px; 
 

 
    text-align: right; 
 
    color: white; 
 
    line-height: 20px; 
 

 
    transition: all 1s ease-in; 
 
    -moz-transition: all 1s ease-in; /* Firefox 4 */ 
 
    -webkit-transition: all 1s ease-in; /* Safari 和 Chrome */ 
 
    -o-transition: all 1s ease-in; /* Opera */ 
 

 
} 
 

 
.element-1 { 
 
    width: 20px; 
 
} 
 

 
.element-2 { 
 
    width: 40px; 
 
} 
 

 
.element-3 { 
 
    width: 60px; 
 
} 
 

 
.element-4 { 
 
    width: 80px; 
 
} 
 

 
.index-1 { 
 
    top: 20px; 
 
} 
 

 
.index-2 { 
 
    top: 40px; 
 
} 
 

 
.index-3 { 
 
    top: 60px; 
 
} 
 

 
.index-4 { 
 
    top: 80px; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.7.2/redux.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/5.0.6/react-redux.js"></script> 
 

 
<div id="root"></div>

関連する問題